From 76d9688a541efa2c3fcd6482a31c781b11e24188 Mon Sep 17 00:00:00 2001 From: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com> Date: Mon, 27 May 2024 11:58:36 +0800 Subject: [PATCH] refactor: db refactor and cache key add. (#2320) * refactor: db refactor and cache key add. * refactor: db refactor and cache key add. * refactor: go version update. * refactor: file name change. --- internal/msgtransfer/init.go | 10 +- .../msgtransfer/online_history_msg_handler.go | 2 +- .../online_msg_to_mongo_handler.go | 2 +- internal/push/offlinepush/fcm/push.go | 2 +- internal/push/offlinepush/getui/push.go | 2 +- internal/push/offlinepush/offlinepusher.go | 2 +- internal/push/push.go | 6 +- internal/rpc/auth/auth.go | 6 +- internal/rpc/conversation/conversaion.go | 34 +- internal/rpc/friend/black.go | 8 +- internal/rpc/friend/friend.go | 21 +- internal/rpc/friend/notification.go | 6 +- internal/rpc/group/callback.go | 4 +- internal/rpc/group/convert.go | 6 +- internal/rpc/group/fill.go | 5 +- internal/rpc/group/group.go | 109 ++--- internal/rpc/group/notification.go | 12 +- internal/rpc/msg/revoke.go | 4 +- internal/rpc/msg/server.go | 10 +- internal/rpc/msg/statistics.go | 6 +- internal/rpc/third/log.go | 12 +- internal/rpc/third/s3.go | 8 +- internal/rpc/third/third.go | 13 +- internal/rpc/user/notification.go | 6 +- internal/rpc/user/user.go | 34 +- pkg/common/config/config.go | 2 +- pkg/common/convert/black.go | 4 +- pkg/common/convert/conversation.go | 14 +- pkg/common/convert/friend.go | 16 +- pkg/common/convert/group.go | 22 +- pkg/common/convert/msg.go | 10 +- pkg/common/convert/user.go | 8 +- pkg/common/convert/user_test.go | 7 +- pkg/common/db/cache/conversation.go | 371 ------------------ pkg/common/db/cache/meta_cache.go | 284 -------------- pkg/common/db/cache/third.go | 85 ---- pkg/common/db/table/relation/doc.go | 15 - pkg/common/storage/cache/batch_handler.go | 17 + pkg/common/storage/cache/black.go | 27 ++ .../{ => storage/cache}/cachekey/black.go | 0 .../cache}/cachekey/conversation.go | 0 .../{ => storage/cache}/cachekey/doc.go | 2 +- .../{ => storage/cache}/cachekey/friend.go | 0 .../{ => storage/cache}/cachekey/group.go | 0 pkg/common/storage/cache/cachekey/msg.go | 70 ++++ pkg/common/storage/cache/cachekey/s3.go | 40 ++ pkg/common/storage/cache/cachekey/seq.go | 38 ++ pkg/common/storage/cache/cachekey/third.go | 41 ++ .../{ => storage/cache}/cachekey/token.go | 0 .../{ => storage/cache}/cachekey/user.go | 5 + pkg/common/storage/cache/conversation.go | 60 +++ pkg/common/{db => storage}/cache/doc.go | 2 +- pkg/common/storage/cache/friend.go | 35 ++ pkg/common/storage/cache/group.go | 62 +++ pkg/common/storage/cache/msg.go | 43 ++ .../storage/cache/redis/batch_handler.go | 211 ++++++++++ .../cache => storage/cache/redis}/black.go | 54 +-- .../storage/cache/redis/conversation.go | 246 ++++++++++++ pkg/common/storage/cache/redis/doc.go | 15 + .../cache => storage/cache/redis}/friend.go | 85 ++-- .../cache => storage/cache/redis}/group.go | 182 ++++----- pkg/common/storage/cache/redis/meta_cache.go | 15 + .../{db/cache => storage/cache/redis}/msg.go | 178 ++------- .../cache => storage/cache/redis}/msg_test.go | 7 +- .../{db/cache => storage/cache/redis}/s3.go | 154 +++----- .../{db/cache => storage/cache/redis}/seq.go | 53 ++- pkg/common/storage/cache/redis/third.go | 103 +++++ .../cache => storage/cache/redis}/token.go | 37 +- .../{db/cache => storage/cache/redis}/user.go | 90 ++--- pkg/common/storage/cache/s3.go | 51 +++ pkg/common/storage/cache/seq.go | 30 ++ pkg/common/storage/cache/third.go | 18 + pkg/common/storage/cache/token.go | 12 + pkg/common/storage/cache/user.go | 33 ++ pkg/common/storage/common/types.go | 26 ++ pkg/common/{db => storage}/controller/auth.go | 2 +- .../{db => storage}/controller/black.go | 32 +- .../controller/conversation.go | 83 ++-- pkg/common/{db => storage}/controller/doc.go | 2 +- .../{db => storage}/controller/friend.go | 80 ++-- .../{db => storage}/controller/group.go | 153 ++++---- pkg/common/{db => storage}/controller/msg.go | 93 ++--- pkg/common/{db => storage}/controller/push.go | 2 +- pkg/common/{db => storage}/controller/s3.go | 20 +- .../{db => storage}/controller/third.go | 21 +- pkg/common/{db => storage}/controller/user.go | 67 ++-- .../relation => storage/database}/black.go | 30 +- .../database}/conversation.go | 42 +- pkg/common/storage/database/doc.go | 15 + .../relation => storage/database}/friend.go | 35 +- .../database}/friend_request.go | 33 +- pkg/common/storage/database/group.go | 35 ++ .../database}/group_member.go | 34 +- .../database}/group_request.go | 31 +- pkg/common/storage/database/log.go | 29 ++ .../{db => storage/database}/mgo/black.go | 29 +- .../database}/mgo/conversation.go | 26 +- .../{db => storage/database}/mgo/doc.go | 2 +- .../{db => storage/database}/mgo/friend.go | 35 +- .../database}/mgo/friend_request.go | 27 +- .../{db => storage/database}/mgo/group.go | 19 +- .../database}/mgo/group_member.go | 21 +- .../database}/mgo/group_request.go | 23 +- .../database/mgo/helpers.go} | 13 +- .../{db => storage/database}/mgo/log.go | 17 +- .../{db => storage/database}/mgo/msg.go | 61 +-- .../{db => storage/database}/mgo/object.go | 13 +- .../{db => storage/database}/mgo/subscribe.go | 11 +- .../{db => storage/database}/mgo/user.go | 35 +- pkg/common/storage/database/msg.go | 48 +++ pkg/common/storage/database/object.go | 26 ++ .../database}/subscribe.go | 21 +- .../relation => storage/database}/user.go | 50 +-- pkg/common/storage/model/black.go | 28 ++ pkg/common/storage/model/conversation.go | 40 ++ pkg/common/storage/model/doc.go | 15 + pkg/common/storage/model/friend.go | 31 ++ pkg/common/storage/model/friend_request.go | 31 ++ .../table/relation => storage/model}/group.go | 20 +- pkg/common/storage/model/group_member.go | 33 ++ pkg/common/storage/model/group_request.go | 33 ++ .../table/relation => storage/model}/log.go | 14 +- .../table/relation => storage/model}/msg.go | 40 +- .../relation => storage/model}/object.go | 11 +- pkg/common/storage/model/subscribe.go | 30 ++ pkg/common/storage/model/user.go | 45 +++ .../db/cache/config.go => localcache/init.go} | 43 +- pkg/rpccache/conversation.go | 2 +- pkg/rpccache/friend.go | 10 +- pkg/rpccache/group.go | 2 +- pkg/rpccache/user.go | 2 +- test/testdata/README.md | 2 +- 132 files changed, 2703 insertions(+), 2255 deletions(-) delete mode 100644 pkg/common/db/cache/conversation.go delete mode 100644 pkg/common/db/cache/meta_cache.go delete mode 100644 pkg/common/db/cache/third.go delete mode 100644 pkg/common/db/table/relation/doc.go create mode 100644 pkg/common/storage/cache/batch_handler.go create mode 100644 pkg/common/storage/cache/black.go rename pkg/common/{ => storage/cache}/cachekey/black.go (100%) rename pkg/common/{ => storage/cache}/cachekey/conversation.go (100%) rename pkg/common/{ => storage/cache}/cachekey/doc.go (95%) rename pkg/common/{ => storage/cache}/cachekey/friend.go (100%) rename pkg/common/{ => storage/cache}/cachekey/group.go (100%) create mode 100644 pkg/common/storage/cache/cachekey/msg.go create mode 100644 pkg/common/storage/cache/cachekey/s3.go create mode 100644 pkg/common/storage/cache/cachekey/seq.go create mode 100644 pkg/common/storage/cache/cachekey/third.go rename pkg/common/{ => storage/cache}/cachekey/token.go (100%) rename pkg/common/{ => storage/cache}/cachekey/user.go (87%) create mode 100644 pkg/common/storage/cache/conversation.go rename pkg/common/{db => storage}/cache/doc.go (96%) create mode 100644 pkg/common/storage/cache/friend.go create mode 100644 pkg/common/storage/cache/group.go create mode 100644 pkg/common/storage/cache/msg.go create mode 100644 pkg/common/storage/cache/redis/batch_handler.go rename pkg/common/{db/cache => storage/cache/redis}/black.go (59%) create mode 100644 pkg/common/storage/cache/redis/conversation.go create mode 100644 pkg/common/storage/cache/redis/doc.go rename pkg/common/{db/cache => storage/cache/redis}/friend.go (67%) rename pkg/common/{db/cache => storage/cache/redis}/group.go (61%) create mode 100644 pkg/common/storage/cache/redis/meta_cache.go rename pkg/common/{db/cache => storage/cache/redis}/msg.go (68%) rename pkg/common/{db/cache => storage/cache/redis}/msg_test.go (99%) rename pkg/common/{db/cache => storage/cache/redis}/s3.go (52%) rename pkg/common/{db/cache => storage/cache/redis}/seq.go (73%) create mode 100644 pkg/common/storage/cache/redis/third.go rename pkg/common/{db/cache => storage/cache/redis}/token.go (60%) rename pkg/common/{db/cache => storage/cache/redis}/user.go (78%) create mode 100644 pkg/common/storage/cache/s3.go create mode 100644 pkg/common/storage/cache/seq.go create mode 100644 pkg/common/storage/cache/third.go create mode 100644 pkg/common/storage/cache/token.go create mode 100644 pkg/common/storage/cache/user.go create mode 100644 pkg/common/storage/common/types.go rename pkg/common/{db => storage}/controller/auth.go (97%) rename pkg/common/{db => storage}/controller/black.go (75%) rename pkg/common/{db => storage}/controller/conversation.go (86%) rename pkg/common/{db => storage}/controller/doc.go (94%) rename pkg/common/{db => storage}/controller/friend.go (82%) rename pkg/common/{db => storage}/controller/group.go (77%) rename pkg/common/{db => storage}/controller/msg.go (93%) rename pkg/common/{db => storage}/controller/push.go (94%) rename pkg/common/{db => storage}/controller/s3.go (84%) rename pkg/common/{db => storage}/controller/third.go (80%) rename pkg/common/{db => storage}/controller/user.go (82%) rename pkg/common/{db/table/relation => storage/database}/black.go (51%) rename pkg/common/{db/table/relation => storage/database}/conversation.go (56%) create mode 100644 pkg/common/storage/database/doc.go rename pkg/common/{db/table/relation => storage/database}/friend.go (70%) rename pkg/common/{db/table/relation => storage/database}/friend_request.go (60%) create mode 100644 pkg/common/storage/database/group.go rename pkg/common/{db/table/relation => storage/database}/group_member.go (56%) rename pkg/common/{db/table/relation => storage/database}/group_request.go (55%) create mode 100644 pkg/common/storage/database/log.go rename pkg/common/{db => storage/database}/mgo/black.go (67%) rename pkg/common/{db => storage/database}/mgo/conversation.go (84%) rename pkg/common/{db => storage/database}/mgo/doc.go (96%) rename pkg/common/{db => storage/database}/mgo/friend.go (80%) rename pkg/common/{db => storage/database}/mgo/friend_request.go (76%) rename pkg/common/{db => storage/database}/mgo/group.go (82%) rename pkg/common/{db => storage/database}/mgo/group_member.go (83%) rename pkg/common/{db => storage/database}/mgo/group_request.go (69%) rename pkg/common/{db/table/relation/utils.go => storage/database/mgo/helpers.go} (80%) rename pkg/common/{db => storage/database}/mgo/log.go (75%) rename pkg/common/{db => storage/database}/mgo/msg.go (91%) rename pkg/common/{db => storage/database}/mgo/object.go (79%) rename pkg/common/{db => storage/database}/mgo/subscribe.go (93%) rename pkg/common/{db => storage/database}/mgo/user.go (87%) create mode 100644 pkg/common/storage/database/msg.go create mode 100644 pkg/common/storage/database/object.go rename pkg/common/{db/table/relation => storage/database}/subscribe.go (74%) rename pkg/common/{db/table/relation => storage/database}/user.go (63%) create mode 100644 pkg/common/storage/model/black.go create mode 100644 pkg/common/storage/model/conversation.go create mode 100644 pkg/common/storage/model/doc.go create mode 100644 pkg/common/storage/model/friend.go create mode 100644 pkg/common/storage/model/friend_request.go rename pkg/common/{db/table/relation => storage/model}/group.go (62%) create mode 100644 pkg/common/storage/model/group_member.go create mode 100644 pkg/common/storage/model/group_request.go rename pkg/common/{db/table/relation => storage/model}/log.go (67%) rename pkg/common/{db/table/relation => storage/model}/msg.go (65%) rename pkg/common/{db/table/relation => storage/model}/object.go (76%) create mode 100644 pkg/common/storage/model/subscribe.go create mode 100644 pkg/common/storage/model/user.go rename pkg/{common/db/cache/config.go => localcache/init.go} (73%) diff --git a/internal/msgtransfer/init.go b/internal/msgtransfer/init.go index 3384b8493..ba82abacf 100644 --- a/internal/msgtransfer/init.go +++ b/internal/msgtransfer/init.go @@ -17,6 +17,8 @@ package msgtransfer import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/redisutil" "github.com/openimsdk/tools/utils/datautil" @@ -26,11 +28,9 @@ import ( "syscall" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" kdisc "github.com/openimsdk/open-im-server/v3/pkg/common/discoveryregister" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" @@ -83,8 +83,8 @@ func Start(ctx context.Context, index int, config *Config) error { client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) //todo MsgCacheTimeout - msgModel := cache.NewMsgCache(rdb, config.RedisConfig.EnablePipeline) - seqModel := cache.NewSeqCache(rdb) + msgModel := redis.NewMsgCache(rdb, config.RedisConfig.EnablePipeline) + seqModel := redis.NewSeqCache(rdb) msgDocModel, err := mgo.NewMsgMongo(mgocli.GetDB()) if err != nil { return err diff --git a/internal/msgtransfer/online_history_msg_handler.go b/internal/msgtransfer/online_history_msg_handler.go index 551e3fe91..194b70187 100644 --- a/internal/msgtransfer/online_history_msg_handler.go +++ b/internal/msgtransfer/online_history_msg_handler.go @@ -25,7 +25,7 @@ import ( "github.com/IBM/sarama" "github.com/go-redis/redis" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" diff --git a/internal/msgtransfer/online_msg_to_mongo_handler.go b/internal/msgtransfer/online_msg_to_mongo_handler.go index c9c035893..0fa9fe0d1 100644 --- a/internal/msgtransfer/online_msg_to_mongo_handler.go +++ b/internal/msgtransfer/online_msg_to_mongo_handler.go @@ -19,8 +19,8 @@ import ( "github.com/IBM/sarama" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" pbmsg "github.com/openimsdk/protocol/msg" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/mq/kafka" diff --git a/internal/push/offlinepush/fcm/push.go b/internal/push/offlinepush/fcm/push.go index 34ad1c0d6..ec973008e 100644 --- a/internal/push/offlinepush/fcm/push.go +++ b/internal/push/offlinepush/fcm/push.go @@ -22,7 +22,7 @@ import ( firebase "firebase.google.com/go" "firebase.google.com/go/messaging" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/errs" "github.com/redis/go-redis/v9" diff --git a/internal/push/offlinepush/getui/push.go b/internal/push/offlinepush/getui/push.go index 8ecea3a62..27b19e8fe 100644 --- a/internal/push/offlinepush/getui/push.go +++ b/internal/push/offlinepush/getui/push.go @@ -24,7 +24,7 @@ import ( "time" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/mcontext" diff --git a/internal/push/offlinepush/offlinepusher.go b/internal/push/offlinepush/offlinepusher.go index d4fcae434..8dc8a0bc6 100644 --- a/internal/push/offlinepush/offlinepusher.go +++ b/internal/push/offlinepush/offlinepusher.go @@ -22,7 +22,7 @@ import ( "github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/jpush" "github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" ) const ( diff --git a/internal/push/push.go b/internal/push/push.go index 2e5c4e526..c7e245dfe 100644 --- a/internal/push/push.go +++ b/internal/push/push.go @@ -4,8 +4,8 @@ import ( "context" "github.com/openimsdk/open-im-server/v3/internal/push/offlinepush" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" pbpush "github.com/openimsdk/protocol/push" "github.com/openimsdk/tools/db/redisutil" "github.com/openimsdk/tools/discovery" @@ -49,7 +49,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } - cacheModel := cache.NewThirdCache(rdb) + cacheModel := redis.NewThirdCache(rdb) offlinePusher, err := offlinepush.NewOfflinePusher(&config.RpcConfig, cacheModel) if err != nil { return err diff --git a/internal/rpc/auth/auth.go b/internal/rpc/auth/auth.go index ddb655398..6270b39b3 100644 --- a/internal/rpc/auth/auth.go +++ b/internal/rpc/auth/auth.go @@ -17,14 +17,14 @@ package auth import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" "github.com/openimsdk/tools/db/redisutil" "github.com/redis/go-redis/v9" "github.com/openimsdk/open-im-server/v3/pkg/authverify" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" pbauth "github.com/openimsdk/protocol/auth" "github.com/openimsdk/protocol/constant" @@ -61,7 +61,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg userRpcClient: &userRpcClient, RegisterCenter: client, authDatabase: controller.NewAuthDatabase( - cache.NewTokenCacheModel(rdb), + redis2.NewTokenCacheModel(rdb), config.Share.Secret, config.RpcConfig.TokenPolicy.Expire, ), diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index 4c7828610..df9267ae0 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -17,15 +17,16 @@ package conversation import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" + tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/tools/db/redisutil" "sort" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" - tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" pbconversation "github.com/openimsdk/protocol/conversation" @@ -73,13 +74,14 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg groupRpcClient := rpcclient.NewGroupRpcClient(client, config.Share.RpcRegisterName.Group) msgRpcClient := rpcclient.NewMessageRpcClient(client, config.Share.RpcRegisterName.Msg) userRpcClient := rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID) - cache.InitLocalCache(&config.LocalCacheConfig) + localcache.InitLocalCache(&config.LocalCacheConfig) pbconversation.RegisterConversationServer(server, &conversationServer{ msgRpcClient: &msgRpcClient, user: &userRpcClient, conversationNotificationSender: NewConversationNotificationSender(&config.NotificationConfig, &msgRpcClient), groupRpcClient: &groupRpcClient, - conversationDatabase: controller.NewConversationDatabase(conversationDB, cache.NewConversationRedis(rdb, &config.LocalCacheConfig, cache.GetDefaultOpt(), conversationDB), mgocli.GetTx()), + conversationDatabase: controller.NewConversationDatabase(conversationDB, + redis.NewConversationRedis(rdb, &config.LocalCacheConfig, redis.GetRocksCacheOptions(), conversationDB), mgocli.GetTx()), }) return nil } @@ -192,11 +194,11 @@ func (c *conversationServer) GetConversations(ctx context.Context, req *pbconver } func (c *conversationServer) SetConversation(ctx context.Context, req *pbconversation.SetConversationReq) (*pbconversation.SetConversationResp, error) { - var conversation tablerelation.ConversationModel + var conversation tablerelation.Conversation if err := datautil.CopyStructFields(&conversation, req.Conversation); err != nil { return nil, err } - err := c.conversationDatabase.SetUserConversations(ctx, req.Conversation.OwnerUserID, []*tablerelation.ConversationModel{&conversation}) + err := c.conversationDatabase.SetUserConversations(ctx, req.Conversation.OwnerUserID, []*tablerelation.Conversation{&conversation}) if err != nil { return nil, err } @@ -220,7 +222,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver } } var unequal int - var conv tablerelation.ConversationModel + var conv tablerelation.Conversation if len(req.UserIDs) == 1 { cs, err := c.conversationDatabase.FindConversations(ctx, req.UserIDs[0], []string{req.Conversation.ConversationID}) if err != nil { @@ -231,7 +233,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver } conv = *cs[0] } - var conversation tablerelation.ConversationModel + var conversation tablerelation.Conversation conversation.ConversationID = req.Conversation.ConversationID conversation.ConversationType = req.Conversation.ConversationType conversation.UserID = req.Conversation.UserID @@ -280,7 +282,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, req *pbconver } } if req.Conversation.IsPrivateChat != nil && req.Conversation.ConversationType != constant.ReadGroupChatType { - var conversations []*tablerelation.ConversationModel + var conversations []*tablerelation.Conversation for _, ownerUserID := range req.UserIDs { conversation2 := conversation conversation2.OwnerUserID = ownerUserID @@ -328,12 +330,12 @@ func (c *conversationServer) CreateSingleChatConversations(ctx context.Context, ) (*pbconversation.CreateSingleChatConversationsResp, error) { switch req.ConversationType { case constant.SingleChatType: - var conversation tablerelation.ConversationModel + var conversation tablerelation.Conversation conversation.ConversationID = req.ConversationID conversation.ConversationType = req.ConversationType conversation.OwnerUserID = req.SendID conversation.UserID = req.RecvID - err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation}) + err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.Conversation{&conversation}) if err != nil { log.ZWarn(ctx, "create conversation failed", err, "conversation", conversation) } @@ -341,17 +343,17 @@ func (c *conversationServer) CreateSingleChatConversations(ctx context.Context, conversation2 := conversation conversation2.OwnerUserID = req.RecvID conversation2.UserID = req.SendID - err = c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation2}) + err = c.conversationDatabase.CreateConversation(ctx, []*tablerelation.Conversation{&conversation2}) if err != nil { log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation) } case constant.NotificationChatType: - var conversation tablerelation.ConversationModel + var conversation tablerelation.Conversation conversation.ConversationID = req.ConversationID conversation.ConversationType = req.ConversationType conversation.OwnerUserID = req.RecvID conversation.UserID = req.SendID - err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.ConversationModel{&conversation}) + err := c.conversationDatabase.CreateConversation(ctx, []*tablerelation.Conversation{&conversation}) if err != nil { log.ZWarn(ctx, "create conversation failed", err, "conversation2", conversation) } diff --git a/internal/rpc/friend/black.go b/internal/rpc/friend/black.go index 1f52286f3..caec08b7a 100644 --- a/internal/rpc/friend/black.go +++ b/internal/rpc/friend/black.go @@ -16,11 +16,11 @@ package friend import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" pbfriend "github.com/openimsdk/protocol/friend" "github.com/openimsdk/tools/mcontext" ) @@ -58,7 +58,7 @@ func (s *friendServer) RemoveBlack(ctx context.Context, req *pbfriend.RemoveBlac return nil, err } - if err := s.blackDatabase.Delete(ctx, []*relation.BlackModel{{OwnerUserID: req.OwnerUserID, BlockUserID: req.BlackUserID}}); err != nil { + if err := s.blackDatabase.Delete(ctx, []*model.Black{{OwnerUserID: req.OwnerUserID, BlockUserID: req.BlackUserID}}); err != nil { return nil, err } @@ -75,7 +75,7 @@ func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) if err != nil { return nil, err } - black := relation.BlackModel{ + black := model.Black{ OwnerUserID: req.OwnerUserID, BlockUserID: req.BlackUserID, OperatorUserID: mcontext.GetOpUserID(ctx), @@ -83,7 +83,7 @@ func (s *friendServer) AddBlack(ctx context.Context, req *pbfriend.AddBlackReq) Ex: req.Ex, } - if err := s.blackDatabase.Create(ctx, []*relation.BlackModel{&black}); err != nil { + if err := s.blackDatabase.Create(ctx, []*model.Black{&black}); err != nil { return nil, err } s.notificationSender.BlackAddedNotification(ctx, req) diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index b49490f26..8b2dea995 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -17,16 +17,17 @@ package friend import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/webhook" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/tools/db/redisutil" "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" - tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" pbfriend "github.com/openimsdk/protocol/friend" @@ -96,19 +97,19 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg &msgRpcClient, WithRpcFunc(userRpcClient.GetUsersInfo), ) - cache.InitLocalCache(&config.LocalCacheConfig) + localcache.InitLocalCache(&config.LocalCacheConfig) // Register Friend server with refactored MongoDB and Redis integrations pbfriend.RegisterFriendServer(server, &friendServer{ friendDatabase: controller.NewFriendDatabase( friendMongoDB, friendRequestMongoDB, - cache.NewFriendCacheRedis(rdb, &config.LocalCacheConfig, friendMongoDB, cache.GetDefaultOpt()), + redis.NewFriendCacheRedis(rdb, &config.LocalCacheConfig, friendMongoDB, redis.GetRocksCacheOptions()), mgocli.GetTx(), ), blackDatabase: controller.NewBlackDatabase( blackMongoDB, - cache.NewBlackCacheRedis(rdb, &config.LocalCacheConfig, blackMongoDB, cache.GetDefaultOpt()), + redis.NewBlackCacheRedis(rdb, &config.LocalCacheConfig, blackMongoDB, redis.GetRocksCacheOptions()), ), userRpcClient: &userRpcClient, notificationSender: notificationSender, @@ -193,7 +194,7 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbfriend.Res return nil, err } - friendRequest := tablerelation.FriendRequestModel{ + friendRequest := model.FriendRequest{ FromUserID: req.FromUserID, ToUserID: req.ToUserID, HandleMsg: req.HandleMsg, @@ -384,10 +385,10 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *pbfrien if err != nil { return nil, err } - friendMap := datautil.SliceToMap(friends, func(e *tablerelation.FriendModel) string { + friendMap := datautil.SliceToMap(friends, func(e *model.Friend) string { return e.FriendUserID }) - blackMap := datautil.SliceToMap(blacks, func(e *tablerelation.BlackModel) string { + blackMap := datautil.SliceToMap(blacks, func(e *model.Black) string { return e.BlockUserID }) resp := &pbfriend.GetSpecifiedFriendsInfoResp{ diff --git a/internal/rpc/friend/notification.go b/internal/rpc/friend/notification.go index f88c9664e..8089a9bdc 100644 --- a/internal/rpc/friend/notification.go +++ b/internal/rpc/friend/notification.go @@ -16,11 +16,11 @@ package friend import ( "context" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" "github.com/openimsdk/protocol/constant" @@ -46,7 +46,7 @@ func WithFriendDB(db controller.FriendDatabase) friendNotificationSenderOptions } func WithDBFunc( - fn func(ctx context.Context, userIDs []string) (users []*relationtb.UserModel, err error), + fn func(ctx context.Context, userIDs []string) (users []*relationtb.User, err error), ) friendNotificationSenderOptions { return func(s *FriendNotificationSender) { f := func(ctx context.Context, userIDs []string) (result []notification.CommonUser, err error) { diff --git a/internal/rpc/group/callback.go b/internal/rpc/group/callback.go index 1690e3973..f31c4587c 100644 --- a/internal/rpc/group/callback.go +++ b/internal/rpc/group/callback.go @@ -19,7 +19,7 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/apistruct" "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/webhook" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/group" @@ -100,7 +100,7 @@ func (s *groupServer) webhookAfterCreateGroup(ctx context.Context, after *config s.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, &callbackstruct.CallbackAfterCreateGroupResp{}, after) } -func (s *groupServer) webhookBeforeMemberJoinGroup(ctx context.Context, before *config.BeforeConfig, groupMember *relation.GroupMemberModel, groupEx string) error { +func (s *groupServer) webhookBeforeMemberJoinGroup(ctx context.Context, before *config.BeforeConfig, groupMember *model.GroupMember, groupEx string) error { return webhook.WithCondition(ctx, before, func(ctx context.Context) error { cbReq := &callbackstruct.CallbackBeforeMemberJoinGroupReq{ CallbackCommand: callbackstruct.CallbackBeforeMemberJoinGroupCommand, diff --git a/internal/rpc/group/convert.go b/internal/rpc/group/convert.go index 86978ce3a..a75693904 100644 --- a/internal/rpc/group/convert.go +++ b/internal/rpc/group/convert.go @@ -15,11 +15,11 @@ package group import ( - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/sdkws" ) -func (s *groupServer) groupDB2PB(group *relation.GroupModel, ownerUserID string, memberCount uint32) *sdkws.GroupInfo { +func (s *groupServer) groupDB2PB(group *model.Group, ownerUserID string, memberCount uint32) *sdkws.GroupInfo { return &sdkws.GroupInfo{ GroupID: group.GroupID, GroupName: group.GroupName, @@ -41,7 +41,7 @@ func (s *groupServer) groupDB2PB(group *relation.GroupModel, ownerUserID string, } } -func (s *groupServer) groupMemberDB2PB(member *relation.GroupMemberModel, appMangerLevel int32) *sdkws.GroupMemberFullInfo { +func (s *groupServer) groupMemberDB2PB(member *model.GroupMember, appMangerLevel int32) *sdkws.GroupMemberFullInfo { return &sdkws.GroupMemberFullInfo{ GroupID: member.GroupID, UserID: member.UserID, diff --git a/internal/rpc/group/fill.go b/internal/rpc/group/fill.go index c504db8d6..1c86481df 100644 --- a/internal/rpc/group/fill.go +++ b/internal/rpc/group/fill.go @@ -16,10 +16,9 @@ package group import ( "context" - - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" ) -func (s *groupServer) PopulateGroupMember(ctx context.Context, members ...*relationtb.GroupMemberModel) error { +func (s *groupServer) PopulateGroupMember(ctx context.Context, members ...*relationtb.GroupMember) error { return s.notification.PopulateGroupMember(ctx, members...) } diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 551554c23..51fd2d7b6 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -18,8 +18,11 @@ import ( "context" "fmt" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/common" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/webhook" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" "math/big" "math/rand" "strconv" @@ -29,10 +32,8 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/grouphash" @@ -110,7 +111,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg } return datautil.Slice(users, func(e *sdkws.UserInfo) notification.CommonUser { return e }), nil }) - cache.InitLocalCache(&config.LocalCacheConfig) + localcache.InitLocalCache(&config.LocalCacheConfig) gs.conversationRpcClient = conversationRpcClient gs.msgRpcClient = msgRpcClient gs.config = config @@ -234,14 +235,14 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR return nil, err } - var groupMembers []*relationtb.GroupMemberModel + var groupMembers []*model.GroupMember group := convert.Pb2DBGroupInfo(req.GroupInfo) if err := s.GenGroupID(ctx, &group.GroupID); err != nil { return nil, err } joinGroup := func(userID string, roleLevel int32) error { - groupMember := &relationtb.GroupMemberModel{ + groupMember := &model.GroupMember{ GroupID: group.GroupID, UserID: userID, RoleLevel: roleLevel, @@ -271,7 +272,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbgroup.CreateGroupR return nil, err } } - if err := s.db.CreateGroup(ctx, []*relationtb.GroupModel{group}, groupMembers); err != nil { + if err := s.db.CreateGroup(ctx, []*model.Group{group}, groupMembers); err != nil { return nil, err } resp := &pbgroup.CreateGroupResp{GroupInfo: &sdkws.GroupInfo{}} @@ -339,7 +340,7 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJo if len(members) == 0 { return &resp, nil } - groupIDs := datautil.Slice(members, func(e *relationtb.GroupMemberModel) string { + groupIDs := datautil.Slice(members, func(e *model.GroupMember) string { return e.GroupID }) groups, err := s.db.FindGroup(ctx, groupIDs) @@ -357,12 +358,12 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbgroup.GetJo if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } - ownerMap := datautil.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { + ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string { return e.GroupID }) - resp.Groups = datautil.Slice(datautil.Order(groupIDs, groups, func(group *relationtb.GroupModel) string { + resp.Groups = datautil.Slice(datautil.Order(groupIDs, groups, func(group *model.Group) string { return group.GroupID - }), func(group *relationtb.GroupModel) *sdkws.GroupInfo { + }), func(group *model.Group) *sdkws.GroupInfo { var userID string if user := ownerMap[group.GroupID]; user != nil { userID = user.UserID @@ -397,7 +398,7 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite return nil, errs.ErrRecordNotFound.WrapMsg("user not found") } - var groupMember *relationtb.GroupMemberModel + var groupMember *model.GroupMember var opUserID string if !authverify.IsAppManagerUid(ctx, s.config.Share.IMAdminUserID) { opUserID = mcontext.GetOpUserID(ctx) @@ -418,9 +419,9 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite if group.NeedVerification == constant.AllNeedVerification { if !authverify.IsAppManagerUid(ctx, s.config.Share.IMAdminUserID) { if !(groupMember.RoleLevel == constant.GroupOwner || groupMember.RoleLevel == constant.GroupAdmin) { - var requests []*relationtb.GroupRequestModel + var requests []*model.GroupRequest for _, userID := range req.InvitedUserIDs { - requests = append(requests, &relationtb.GroupRequestModel{ + requests = append(requests, &model.GroupRequest{ UserID: userID, GroupID: req.GroupID, JoinSource: constant.JoinByInvitation, @@ -444,9 +445,9 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbgroup.Invite } } } - var groupMembers []*relationtb.GroupMemberModel + var groupMembers []*model.GroupMember for _, userID := range req.InvitedUserIDs { - member := &relationtb.GroupMemberModel{ + member := &model.GroupMember{ GroupID: req.GroupID, UserID: userID, RoleLevel: constant.GroupOrdinaryUsers, @@ -482,7 +483,7 @@ func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro return nil, err } var resp pbgroup.GetGroupAllMemberResp - resp.Members = datautil.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { + resp.Members = datautil.Slice(members, func(e *model.GroupMember) *sdkws.GroupMemberFullInfo { return convert.Db2PbGroupMember(e) }) return &resp, nil @@ -491,7 +492,7 @@ func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) { var ( total int64 - members []*relationtb.GroupMemberModel + members []*model.GroupMember err error ) if req.Keyword == "" { @@ -506,7 +507,7 @@ func (s *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGr return nil, err } if req.Keyword != "" { - groupMembers := make([]*relationtb.GroupMemberModel, 0) + groupMembers := make([]*model.GroupMember, 0) for _, member := range members { if member.UserID == req.Keyword { groupMembers = append(groupMembers, member) @@ -554,7 +555,7 @@ func (s *groupServer) KickGroupMember(ctx context.Context, req *pbgroup.KickGrou if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } - memberMap := make(map[string]*relationtb.GroupMemberModel) + memberMap := make(map[string]*model.GroupMember) for i, member := range members { memberMap[member.UserID] = members[i] } @@ -649,7 +650,7 @@ func (s *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbgroup.GetG return nil, err } return &pbgroup.GetGroupMembersInfoResp{ - Members: datautil.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { + Members: datautil.Slice(members, func(e *model.GroupMember) *sdkws.GroupMemberFullInfo { return convert.Db2PbGroupMember(e) }), }, nil @@ -687,7 +688,7 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup. if err != nil { return nil, err } - groupMap := datautil.SliceToMap(groups, func(e *relationtb.GroupModel) string { + groupMap := datautil.SliceToMap(groups, func(e *model.Group) string { return e.GroupID }) if ids := datautil.Single(datautil.Keys(groupMap), groupIDs); len(ids) > 0 { @@ -704,10 +705,10 @@ func (s *groupServer) GetGroupApplicationList(ctx context.Context, req *pbgroup. if err := s.PopulateGroupMember(ctx, owners...); err != nil { return nil, err } - ownerMap := datautil.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { + ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string { return e.GroupID }) - resp.GroupRequests = datautil.Slice(groupRequests, func(e *relationtb.GroupRequestModel) *sdkws.GroupRequest { + resp.GroupRequests = datautil.Slice(groupRequests, func(e *model.GroupRequest) *sdkws.GroupRequest { var ownerUserID string if owner, ok := ownerMap[e.GroupID]; ok { ownerUserID = owner.UserID @@ -736,11 +737,11 @@ func (s *groupServer) GetGroupsInfo(ctx context.Context, req *pbgroup.GetGroupsI if err := s.PopulateGroupMember(ctx, owners...); err != nil { return nil, err } - ownerMap := datautil.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { + ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string { return e.GroupID }) return &pbgroup.GetGroupsInfoResp{ - GroupInfos: datautil.Slice(groups, func(e *relationtb.GroupModel) *sdkws.GroupInfo { + GroupInfos: datautil.Slice(groups, func(e *model.Group) *sdkws.GroupInfo { var ownerUserID string if owner, ok := ownerMap[e.GroupID]; ok { ownerUserID = owner.UserID @@ -783,9 +784,9 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup if _, err := s.user.GetPublicUserInfo(ctx, req.FromUserID); err != nil { return nil, err } - var member *relationtb.GroupMemberModel + var member *model.GroupMember if (!inGroup) && req.HandleResult == constant.GroupResponseAgree { - member = &relationtb.GroupMemberModel{ + member = &model.GroupMember{ GroupID: req.GroupID, UserID: req.FromUserID, Nickname: "", @@ -857,7 +858,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) } log.ZDebug(ctx, "JoinGroup.groupInfo", "group", group, "eq", group.NeedVerification == constant.Directly) if group.NeedVerification == constant.Directly { - groupMember := &relationtb.GroupMemberModel{ + groupMember := &model.GroupMember{ GroupID: group.GroupID, UserID: user.UserID, RoleLevel: constant.GroupOrdinaryUsers, @@ -871,7 +872,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) return nil, err } - if err := s.db.CreateGroup(ctx, nil, []*relationtb.GroupMemberModel{groupMember}); err != nil { + if err := s.db.CreateGroup(ctx, nil, []*model.GroupMember{groupMember}); err != nil { return nil, err } @@ -883,7 +884,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) return &pbgroup.JoinGroupResp{}, nil } - groupRequest := relationtb.GroupRequestModel{ + groupRequest := model.GroupRequest{ UserID: req.InviterUserID, ReqMsg: req.ReqMessage, GroupID: req.GroupID, @@ -892,7 +893,7 @@ func (s *groupServer) JoinGroup(ctx context.Context, req *pbgroup.JoinGroupReq) HandledTime: time.Unix(0, 0), Ex: req.Ex, } - if err = s.db.CreateGroupRequest(ctx, []*relationtb.GroupRequestModel{&groupRequest}); err != nil { + if err = s.db.CreateGroupRequest(ctx, []*model.GroupRequest{&groupRequest}); err != nil { return nil, err } s.notification.JoinGroupApplicationNotification(ctx, req) @@ -940,7 +941,7 @@ func (s *groupServer) deleteMemberAndSetConversationSeq(ctx context.Context, gro } func (s *groupServer) SetGroupInfo(ctx context.Context, req *pbgroup.SetGroupInfoReq) (*pbgroup.SetGroupInfoResp, error) { - var opMember *relationtb.GroupMemberModel + var opMember *model.GroupMember if !authverify.IsAppManagerUid(ctx, s.config.Share.IMAdminUserID) { var err error opMember, err = s.db.TakeGroupMember(ctx, req.GroupInfoForSet.GroupID, mcontext.GetOpUserID(ctx)) @@ -1049,7 +1050,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } - memberMap := datautil.SliceToMap(members, func(e *relationtb.GroupMemberModel) string { return e.UserID }) + memberMap := datautil.SliceToMap(members, func(e *model.GroupMember) string { return e.UserID }) if ids := datautil.Single([]string{req.OldOwnerUserID, req.NewOwnerUserID}, datautil.Keys(memberMap)); len(ids) > 0 { return nil, errs.ErrArgs.WrapMsg("user not in group " + strings.Join(ids, ",")) } @@ -1078,7 +1079,7 @@ func (s *groupServer) TransferGroupOwner(ctx context.Context, req *pbgroup.Trans func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) (*pbgroup.GetGroupsResp, error) { var ( - group []*relationtb.GroupModel + group []*model.Group err error ) var resp pbgroup.GetGroupsResp @@ -1095,7 +1096,7 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) return nil, err } - groupIDs := datautil.Slice(group, func(e *relationtb.GroupModel) string { + groupIDs := datautil.Slice(group, func(e *model.Group) string { return e.GroupID }) @@ -1104,14 +1105,14 @@ func (s *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) return nil, err } - ownerMemberMap := datautil.SliceToMap(ownerMembers, func(e *relationtb.GroupMemberModel) string { + ownerMemberMap := datautil.SliceToMap(ownerMembers, func(e *model.GroupMember) string { return e.GroupID }) groupMemberNumMap, err := s.db.MapGroupMemberNum(ctx, groupIDs) if err != nil { return nil, err } - resp.Groups = datautil.Slice(group, func(group *relationtb.GroupModel) *pbgroup.CMSGroup { + resp.Groups = datautil.Slice(group, func(group *model.Group) *pbgroup.CMSGroup { var ( userID string username string @@ -1135,7 +1136,7 @@ func (s *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGr if err := s.PopulateGroupMember(ctx, members...); err != nil { return nil, err } - resp.Members = datautil.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { + resp.Members = datautil.Slice(members, func(e *model.GroupMember) *sdkws.GroupMemberFullInfo { return convert.Db2PbGroupMember(e) }) return &resp, nil @@ -1153,14 +1154,14 @@ func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgrou if len(requests) == 0 { return &pbgroup.GetUserReqApplicationListResp{Total: uint32(total)}, nil } - groupIDs := datautil.Distinct(datautil.Slice(requests, func(e *relationtb.GroupRequestModel) string { + groupIDs := datautil.Distinct(datautil.Slice(requests, func(e *model.GroupRequest) string { return e.GroupID })) groups, err := s.db.FindGroup(ctx, groupIDs) if err != nil { return nil, err } - groupMap := datautil.SliceToMap(groups, func(e *relationtb.GroupModel) string { + groupMap := datautil.SliceToMap(groups, func(e *model.Group) string { return e.GroupID }) owners, err := s.db.FindGroupsOwner(ctx, groupIDs) @@ -1170,7 +1171,7 @@ func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgrou if err := s.PopulateGroupMember(ctx, owners...); err != nil { return nil, err } - ownerMap := datautil.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { + ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string { return e.GroupID }) groupMemberNum, err := s.db.MapGroupMemberNum(ctx, groupIDs) @@ -1179,7 +1180,7 @@ func (s *groupServer) GetUserReqApplicationList(ctx context.Context, req *pbgrou } return &pbgroup.GetUserReqApplicationListResp{ Total: uint32(total), - GroupRequests: datautil.Slice(requests, func(e *relationtb.GroupRequestModel) *sdkws.GroupRequest { + GroupRequests: datautil.Slice(requests, func(e *model.GroupRequest) *sdkws.GroupRequest { var ownerUserID string if owner, ok := ownerMap[e.GroupID]; ok { ownerUserID = owner.UserID @@ -1430,8 +1431,8 @@ func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbgroup.SetGr } } - if err := s.db.UpdateGroupMembers(ctx, datautil.Slice(req.Members, func(e *pbgroup.SetGroupMemberInfo) *relationtb.BatchUpdateGroupMember { - return &relationtb.BatchUpdateGroupMember{ + if err := s.db.UpdateGroupMembers(ctx, datautil.Slice(req.Members, func(e *pbgroup.SetGroupMemberInfo) *common.BatchUpdateGroupMember { + return &common.BatchUpdateGroupMember{ GroupID: e.GroupID, UserID: e.UserID, Map: UpdateGroupMemberMap(e), @@ -1470,7 +1471,7 @@ func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbgroup.Get if err != nil { return nil, err } - if ids := datautil.Single(req.GroupIDs, datautil.Slice(groups, func(group *relationtb.GroupModel) string { + if ids := datautil.Single(req.GroupIDs, datautil.Slice(groups, func(group *model.Group) string { return group.GroupID })); len(ids) > 0 { return nil, servererrs.ErrGroupIDNotFound.WrapMsg("not found group " + strings.Join(ids, ",")) @@ -1483,7 +1484,7 @@ func (s *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbgroup.Get return nil, servererrs.ErrGroupIDNotFound.WrapMsg(fmt.Sprintf("group %s not found member", strings.Join(ids, ","))) } return &pbgroup.GetGroupAbstractInfoResp{ - GroupAbstractInfos: datautil.Slice(groups, func(group *relationtb.GroupModel) *pbgroup.GroupAbstractInfo { + GroupAbstractInfos: datautil.Slice(groups, func(group *model.Group) *pbgroup.GroupAbstractInfo { users := groupUserMap[group.GroupID] return convert.Db2PbGroupAbstractInfo(group.GroupID, users.MemberNum, users.Hash) }), @@ -1502,7 +1503,7 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge return nil, err } return &pbgroup.GetUserInGroupMembersResp{ - Members: datautil.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { + Members: datautil.Slice(members, func(e *model.GroupMember) *sdkws.GroupMemberFullInfo { return convert.Db2PbGroupMember(e) }), }, nil @@ -1530,7 +1531,7 @@ func (s *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req *pbgroup. return nil, err } return &pbgroup.GetGroupMemberRoleLevelResp{ - Members: datautil.Slice(members, func(e *relationtb.GroupMemberModel) *sdkws.GroupMemberFullInfo { + Members: datautil.Slice(members, func(e *model.GroupMember) *sdkws.GroupMemberFullInfo { return convert.Db2PbGroupMember(e) }), }, nil @@ -1544,14 +1545,14 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * if len(requests) == 0 { return &pbgroup.GetGroupUsersReqApplicationListResp{}, nil } - groupIDs := datautil.Distinct(datautil.Slice(requests, func(e *relationtb.GroupRequestModel) string { + groupIDs := datautil.Distinct(datautil.Slice(requests, func(e *model.GroupRequest) string { return e.GroupID })) groups, err := s.db.FindGroup(ctx, groupIDs) if err != nil { return nil, err } - groupMap := datautil.SliceToMap(groups, func(e *relationtb.GroupModel) string { + groupMap := datautil.SliceToMap(groups, func(e *model.Group) string { return e.GroupID }) if ids := datautil.Single(groupIDs, datautil.Keys(groupMap)); len(ids) > 0 { @@ -1564,7 +1565,7 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * if err := s.PopulateGroupMember(ctx, owners...); err != nil { return nil, err } - ownerMap := datautil.SliceToMap(owners, func(e *relationtb.GroupMemberModel) string { + ownerMap := datautil.SliceToMap(owners, func(e *model.GroupMember) string { return e.GroupID }) groupMemberNum, err := s.db.MapGroupMemberNum(ctx, groupIDs) @@ -1573,7 +1574,7 @@ func (s *groupServer) GetGroupUsersReqApplicationList(ctx context.Context, req * } return &pbgroup.GetGroupUsersReqApplicationListResp{ Total: int64(len(requests)), - GroupRequests: datautil.Slice(requests, func(e *relationtb.GroupRequestModel) *sdkws.GroupRequest { + GroupRequests: datautil.Slice(requests, func(e *model.GroupRequest) *sdkws.GroupRequest { var ownerUserID string if owner, ok := ownerMap[e.GroupID]; ok { ownerUserID = owner.UserID diff --git a/internal/rpc/group/notification.go b/internal/rpc/group/notification.go index 6d7cebcbc..f0f054d0a 100644 --- a/internal/rpc/group/notification.go +++ b/internal/rpc/group/notification.go @@ -17,12 +17,12 @@ package group import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" "github.com/openimsdk/open-im-server/v3/pkg/authverify" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" pbgroup "github.com/openimsdk/protocol/group" @@ -50,7 +50,7 @@ type GroupNotificationSender struct { config *Config } -func (g *GroupNotificationSender) PopulateGroupMember(ctx context.Context, members ...*relation.GroupMemberModel) error { +func (g *GroupNotificationSender) PopulateGroupMember(ctx context.Context, members ...*model.GroupMember) error { if len(members) == 0 { return nil } @@ -186,12 +186,12 @@ func (g *GroupNotificationSender) getGroupOwnerAndAdminUserID(ctx context.Contex if err := g.PopulateGroupMember(ctx, members...); err != nil { return nil, err } - fn := func(e *relation.GroupMemberModel) string { return e.UserID } + fn := func(e *model.GroupMember) string { return e.UserID } return datautil.Slice(members, fn), nil } //nolint:unused -func (g *GroupNotificationSender) groupDB2PB(group *relation.GroupModel, ownerUserID string, memberCount uint32) *sdkws.GroupInfo { +func (g *GroupNotificationSender) groupDB2PB(group *model.Group, ownerUserID string, memberCount uint32) *sdkws.GroupInfo { return &sdkws.GroupInfo{ GroupID: group.GroupID, GroupName: group.GroupName, @@ -213,7 +213,7 @@ func (g *GroupNotificationSender) groupDB2PB(group *relation.GroupModel, ownerUs } } -func (g *GroupNotificationSender) groupMemberDB2PB(member *relation.GroupMemberModel, appMangerLevel int32) *sdkws.GroupMemberFullInfo { +func (g *GroupNotificationSender) groupMemberDB2PB(member *model.GroupMember, appMangerLevel int32) *sdkws.GroupMemberFullInfo { return &sdkws.GroupMemberFullInfo{ GroupID: member.GroupID, UserID: member.UserID, diff --git a/internal/rpc/msg/revoke.go b/internal/rpc/msg/revoke.go index 7dbc307a1..b7cc7df62 100644 --- a/internal/rpc/msg/revoke.go +++ b/internal/rpc/msg/revoke.go @@ -17,10 +17,10 @@ package msg import ( "context" "encoding/json" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" "github.com/openimsdk/open-im-server/v3/pkg/authverify" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/msg" @@ -93,7 +93,7 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg. } } now := time.Now().UnixMilli() - err = m.MsgDatabase.RevokeMsg(ctx, req.ConversationID, req.Seq, &relation.RevokeModel{ + err = m.MsgDatabase.RevokeMsg(ctx, req.ConversationID, req.Seq, &model.RevokeModel{ Role: role, UserID: req.UserID, Nickname: user.Nickname, diff --git a/internal/rpc/msg/server.go b/internal/rpc/msg/server.go index 5d7c0b297..6ff45605e 100644 --- a/internal/rpc/msg/server.go +++ b/internal/rpc/msg/server.go @@ -17,14 +17,14 @@ package msg import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" "github.com/openimsdk/open-im-server/v3/pkg/common/webhook" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/redisutil" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpccache" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" @@ -86,8 +86,8 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg return err } //todo MsgCacheTimeout - msgModel := cache.NewMsgCache(rdb, config.RedisConfig.EnablePipeline) - seqModel := cache.NewSeqCache(rdb) + msgModel := redis.NewMsgCache(rdb, config.RedisConfig.EnablePipeline) + seqModel := redis.NewSeqCache(rdb) conversationClient := rpcclient.NewConversationRpcClient(client, config.Share.RpcRegisterName.Conversation) userRpcClient := rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID) groupRpcClient := rpcclient.NewGroupRpcClient(client, config.Share.RpcRegisterName.Group) diff --git a/internal/rpc/msg/statistics.go b/internal/rpc/msg/statistics.go index 15a0aaa57..01c0f1c46 100644 --- a/internal/rpc/msg/statistics.go +++ b/internal/rpc/msg/statistics.go @@ -16,9 +16,9 @@ package msg import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/msg" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/utils/datautil" @@ -31,7 +31,7 @@ func (m *msgServer) GetActiveUser(ctx context.Context, req *msg.GetActiveUserReq } var pbUsers []*msg.ActiveUser if len(users) > 0 { - userIDs := datautil.Slice(users, func(e *relation.UserCount) string { return e.UserID }) + userIDs := datautil.Slice(users, func(e *model.UserCount) string { return e.UserID }) userMap, err := m.UserLocalCache.GetUsersInfoMap(ctx, userIDs) if err != nil { return nil, err @@ -66,7 +66,7 @@ func (m *msgServer) GetActiveGroup(ctx context.Context, req *msg.GetActiveGroupR } var pbgroups []*msg.ActiveGroup if len(groups) > 0 { - groupIDs := datautil.Slice(groups, func(e *relation.GroupCount) string { return e.GroupID }) + groupIDs := datautil.Slice(groups, func(e *model.GroupCount) string { return e.GroupID }) resp, err := m.GroupLocalCache.GetGroupInfos(ctx, groupIDs) if err != nil { return nil, err diff --git a/internal/rpc/third/log.go b/internal/rpc/third/log.go index 7712851ed..5c0b1f2e6 100644 --- a/internal/rpc/third/log.go +++ b/internal/rpc/third/log.go @@ -17,10 +17,10 @@ package third import ( "context" "crypto/rand" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" "github.com/openimsdk/open-im-server/v3/pkg/authverify" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/third" @@ -45,11 +45,11 @@ func genLogID() string { } func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq) (*third.UploadLogsResp, error) { - var dbLogs []*relationtb.LogModel + var dbLogs []*relationtb.Log userID := ctx.Value(constant.OpUserID).(string) platform := constant.PlatformID2Name[int(req.Platform)] for _, fileURL := range req.FileURLs { - log := relationtb.LogModel{ + log := relationtb.Log{ Version: req.Version, SystemType: req.SystemType, Platform: platform, @@ -70,7 +70,7 @@ func (t *thirdServer) UploadLogs(ctx context.Context, req *third.UploadLogsReq) } } if log.LogID == "" { - return nil, servererrs.ErrData.WrapMsg("LogModel id gen error") + return nil, servererrs.ErrData.WrapMsg("Log id gen error") } dbLogs = append(dbLogs, &log) } @@ -105,8 +105,8 @@ func (t *thirdServer) DeleteLogs(ctx context.Context, req *third.DeleteLogsReq) return &third.DeleteLogsResp{}, nil } -func dbToPbLogInfos(logs []*relationtb.LogModel) []*third.LogInfo { - db2pbForLogInfo := func(log *relationtb.LogModel) *third.LogInfo { +func dbToPbLogInfos(logs []*relationtb.Log) []*third.LogInfo { + db2pbForLogInfo := func(log *relationtb.Log) *third.LogInfo { return &third.LogInfo{ Filename: log.FileName, UserID: log.UserID, diff --git a/internal/rpc/third/s3.go b/internal/rpc/third/s3.go index 21d982268..4cb1b81d0 100644 --- a/internal/rpc/third/s3.go +++ b/internal/rpc/third/s3.go @@ -19,12 +19,12 @@ import ( "encoding/base64" "encoding/hex" "encoding/json" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "path" "strconv" "time" "github.com/google/uuid" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" "github.com/openimsdk/protocol/third" "github.com/openimsdk/tools/errs" @@ -60,7 +60,7 @@ func (t *thirdServer) InitiateMultipartUpload(ctx context.Context, req *third.In result, err := t.s3dataBase.InitiateMultipartUpload(ctx, req.Hash, req.Size, t.defaultExpire, int(req.MaxParts)) if err != nil { if haErr, ok := errs.Unwrap(err).(*cont.HashAlreadyExistsError); ok { - obj := &relation.ObjectModel{ + obj := &model.Object{ Name: req.Name, UserID: mcontext.GetOpUserID(ctx), Hash: req.Hash, @@ -137,7 +137,7 @@ func (t *thirdServer) CompleteMultipartUpload(ctx context.Context, req *third.Co if err != nil { return nil, err } - obj := &relation.ObjectModel{ + obj := &model.Object{ Name: req.Name, UserID: mcontext.GetOpUserID(ctx), Hash: result.Hash, @@ -263,7 +263,7 @@ func (t *thirdServer) CompleteFormData(ctx context.Context, req *third.CompleteF if info.Size > 0 && info.Size != mate.Size { return nil, servererrs.ErrData.WrapMsg("file size mismatch") } - obj := &relation.ObjectModel{ + obj := &model.Object{ Name: mate.Name, UserID: mcontext.GetOpUserID(ctx), Hash: "etag_" + info.ETag, diff --git a/internal/rpc/third/third.go b/internal/rpc/third/third.go index a3d9085d3..7560486a0 100644 --- a/internal/rpc/third/third.go +++ b/internal/rpc/third/third.go @@ -18,11 +18,12 @@ import ( "context" "fmt" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/third" "github.com/openimsdk/tools/db/mongoutil" @@ -75,7 +76,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg var o s3.Interface switch enable { case "minio": - o, err = minio.NewMinio(ctx, cache.NewMinioCache(rdb), *config.MinioConfig.Build()) + o, err = minio.NewMinio(ctx, redis.NewMinioCache(rdb), *config.MinioConfig.Build()) case "cos": o, err = cos.NewCos(*config.RpcConfig.Object.Cos.Build()) case "oss": @@ -86,9 +87,9 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg if err != nil { return err } - cache.InitLocalCache(&config.LocalCacheConfig) + localcache.InitLocalCache(&config.LocalCacheConfig) third.RegisterThirdServer(server, &thirdServer{ - thirdDatabase: controller.NewThirdDatabase(cache.NewThirdCache(rdb), logdb), + thirdDatabase: controller.NewThirdDatabase(redis.NewThirdCache(rdb), logdb), userRpcClient: rpcclient.NewUserRpcClient(client, config.Share.RpcRegisterName.User, config.Share.IMAdminUserID), s3dataBase: controller.NewS3Database(rdb, o, s3db), defaultExpire: time.Hour * 24 * 7, diff --git a/internal/rpc/user/notification.go b/internal/rpc/user/notification.go index 348cd5628..b992c9d12 100644 --- a/internal/rpc/user/notification.go +++ b/internal/rpc/user/notification.go @@ -16,10 +16,10 @@ package user import ( "context" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient/notification" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" @@ -41,7 +41,7 @@ func WithUserDB(db controller.UserDatabase) userNotificationSenderOptions { } func WithUserFunc( - fn func(ctx context.Context, userIDs []string) (users []*relationtb.UserModel, err error), + fn func(ctx context.Context, userIDs []string) (users []*relationtb.User, err error), ) userNotificationSenderOptions { return func(u *UserNotificationSender) { f := func(ctx context.Context, userIDs []string) (result []notification.CommonUser, err error) { diff --git a/internal/rpc/user/user.go b/internal/rpc/user/user.go index a28fa24e2..d0d3dbf60 100644 --- a/internal/rpc/user/user.go +++ b/internal/rpc/user/user.go @@ -18,7 +18,11 @@ import ( "context" "github.com/openimsdk/open-im-server/v3/internal/rpc/friend" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" + tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/open-im-server/v3/pkg/common/webhook" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/tools/db/redisutil" "math/rand" "strings" @@ -26,12 +30,8 @@ import ( "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - tablerelation "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/servererrs" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" @@ -77,22 +77,22 @@ func Start(ctx context.Context, config *Config, client registry.SvcDiscoveryRegi if err != nil { return err } - users := make([]*tablerelation.UserModel, 0) + users := make([]*tablerelation.User, 0) for _, v := range config.Share.IMAdminUserID { - users = append(users, &tablerelation.UserModel{UserID: v, Nickname: v, AppMangerLevel: constant.AppNotificationAdmin}) + users = append(users, &tablerelation.User{UserID: v, Nickname: v, AppMangerLevel: constant.AppNotificationAdmin}) } userDB, err := mgo.NewUserMongo(mgocli.GetDB()) if err != nil { return err } - userCache := cache.NewUserCacheRedis(rdb, &config.LocalCacheConfig, userDB, cache.GetDefaultOpt()) + userCache := redis.NewUserCacheRedis(rdb, &config.LocalCacheConfig, userDB, redis.GetRocksCacheOptions()) userMongoDB := mgo.NewUserMongoDriver(mgocli.GetDB()) database := controller.NewUserDatabase(userDB, userCache, mgocli.GetTx(), userMongoDB) friendRpcClient := rpcclient.NewFriendRpcClient(client, config.Share.RpcRegisterName.Friend) groupRpcClient := rpcclient.NewGroupRpcClient(client, config.Share.RpcRegisterName.Group) msgRpcClient := rpcclient.NewMessageRpcClient(client, config.Share.RpcRegisterName.Msg) - cache.InitLocalCache(&config.LocalCacheConfig) + localcache.InitLocalCache(&config.LocalCacheConfig) u := &userServer{ db: database, RegisterCenter: client, @@ -281,9 +281,9 @@ func (s *userServer) UserRegister(ctx context.Context, req *pbuser.UserRegisterR return nil, err } now := time.Now() - users := make([]*tablerelation.UserModel, 0, len(req.Users)) + users := make([]*tablerelation.User, 0, len(req.Users)) for _, user := range req.Users { - users = append(users, &tablerelation.UserModel{ + users = append(users, &tablerelation.User{ UserID: user.UserID, Nickname: user.Nickname, FaceURL: user.FaceURL, @@ -403,7 +403,7 @@ func (s *userServer) ProcessUserCommandAdd(ctx context.Context, req *pbuser.Proc if req.Ex != nil { value = req.Ex.Value } - // Assuming you have a method in s.db to add a user command + // Assuming you have a method in s.storage to add a user command err = s.db.AddUserCommand(ctx, req.UserID, req.Type, req.Uuid, value, ex) if err != nil { return nil, err @@ -451,7 +451,7 @@ func (s *userServer) ProcessUserCommandUpdate(ctx context.Context, req *pbuser.P val["ex"] = req.Ex.Value } - // Assuming you have a method in s.db to update a user command + // Assuming you have a method in s.storage to update a user command err = s.db.UpdateUserCommand(ctx, req.UserID, req.Type, req.Uuid, val) if err != nil { return nil, err @@ -548,14 +548,14 @@ func (s *userServer) AddNotificationAccount(ctx context.Context, req *pbuser.Add } } - user := &tablerelation.UserModel{ + user := &tablerelation.User{ UserID: req.UserID, Nickname: req.NickName, FaceURL: req.FaceURL, CreateTime: time.Now(), AppMangerLevel: constant.AppNotificationAdmin, } - if err := s.db.Create(ctx, []*tablerelation.UserModel{user}); err != nil { + if err := s.db.Create(ctx, []*tablerelation.User{user}); err != nil { return nil, err } @@ -598,7 +598,7 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser. return nil, err } - var users []*relation.UserModel + var users []*tablerelation.User var err error // If a keyword is provided in the request @@ -664,7 +664,7 @@ func (s *userServer) genUserID() string { return string(data) } -func (s *userServer) userModelToResp(users []*relation.UserModel, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp { +func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp { accounts := make([]*pbuser.NotificationAccountInfo, 0) var total int64 for _, v := range users { diff --git a/pkg/common/config/config.go b/pkg/common/config/config.go index 12c4f7f78..a75d45ebb 100644 --- a/pkg/common/config/config.go +++ b/pkg/common/config/config.go @@ -328,7 +328,7 @@ type Redis struct { Password string `mapstructure:"password"` EnablePipeline bool `mapstructure:"enablePipeline"` ClusterMode bool `mapstructure:"clusterMode"` - DB int `mapstructure:"db"` + DB int `mapstructure:"storage"` MaxRetry int `mapstructure:"MaxRetry"` } diff --git a/pkg/common/convert/black.go b/pkg/common/convert/black.go index 635b1a586..6c24051fd 100644 --- a/pkg/common/convert/black.go +++ b/pkg/common/convert/black.go @@ -16,13 +16,13 @@ package convert import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/sdkws" sdk "github.com/openimsdk/protocol/sdkws" ) -func BlackDB2Pb(ctx context.Context, blackDBs []*relation.BlackModel, f func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error)) (blackPbs []*sdk.BlackInfo, err error) { +func BlackDB2Pb(ctx context.Context, blackDBs []*model.Black, f func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error)) (blackPbs []*sdk.BlackInfo, err error) { if len(blackDBs) == 0 { return nil, nil } diff --git a/pkg/common/convert/conversation.go b/pkg/common/convert/conversation.go index 510f40d70..a76d7d9f6 100644 --- a/pkg/common/convert/conversation.go +++ b/pkg/common/convert/conversation.go @@ -15,12 +15,12 @@ package convert import ( - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/conversation" "github.com/openimsdk/tools/utils/datautil" ) -func ConversationDB2Pb(conversationDB *relation.ConversationModel) *conversation.Conversation { +func ConversationDB2Pb(conversationDB *model.Conversation) *conversation.Conversation { conversationPB := &conversation.Conversation{} conversationPB.LatestMsgDestructTime = conversationDB.LatestMsgDestructTime.Unix() if err := datautil.CopyStructFields(conversationPB, conversationDB); err != nil { @@ -29,7 +29,7 @@ func ConversationDB2Pb(conversationDB *relation.ConversationModel) *conversation return conversationPB } -func ConversationsDB2Pb(conversationsDB []*relation.ConversationModel) (conversationsPB []*conversation.Conversation) { +func ConversationsDB2Pb(conversationsDB []*model.Conversation) (conversationsPB []*conversation.Conversation) { for _, conversationDB := range conversationsDB { conversationPB := &conversation.Conversation{} if err := datautil.CopyStructFields(conversationPB, conversationDB); err != nil { @@ -41,17 +41,17 @@ func ConversationsDB2Pb(conversationsDB []*relation.ConversationModel) (conversa return conversationsPB } -func ConversationPb2DB(conversationPB *conversation.Conversation) *relation.ConversationModel { - conversationDB := &relation.ConversationModel{} +func ConversationPb2DB(conversationPB *conversation.Conversation) *model.Conversation { + conversationDB := &model.Conversation{} if err := datautil.CopyStructFields(conversationDB, conversationPB); err != nil { return nil } return conversationDB } -func ConversationsPb2DB(conversationsPB []*conversation.Conversation) (conversationsDB []*relation.ConversationModel) { +func ConversationsPb2DB(conversationsPB []*conversation.Conversation) (conversationsDB []*model.Conversation) { for _, conversationPB := range conversationsPB { - conversationDB := &relation.ConversationModel{} + conversationDB := &model.Conversation{} if err := datautil.CopyStructFields(conversationDB, conversationPB); err != nil { continue } diff --git a/pkg/common/convert/friend.go b/pkg/common/convert/friend.go index ad8f9071e..8d6cfad18 100644 --- a/pkg/common/convert/friend.go +++ b/pkg/common/convert/friend.go @@ -17,15 +17,15 @@ package convert import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/utils/datautil" "github.com/openimsdk/tools/utils/timeutil" ) -func FriendPb2DB(friend *sdkws.FriendInfo) *relation.FriendModel { - dbFriend := &relation.FriendModel{} +func FriendPb2DB(friend *sdkws.FriendInfo) *model.Friend { + dbFriend := &model.Friend{} err := datautil.CopyStructFields(dbFriend, friend) if err != nil { return nil @@ -35,7 +35,7 @@ func FriendPb2DB(friend *sdkws.FriendInfo) *relation.FriendModel { return dbFriend } -func FriendDB2Pb(ctx context.Context, friendDB *relation.FriendModel, +func FriendDB2Pb(ctx context.Context, friendDB *model.Friend, getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error), ) (*sdkws.FriendInfo, error) { users, err := getUsers(ctx, []string{friendDB.FriendUserID}) @@ -55,7 +55,7 @@ func FriendDB2Pb(ctx context.Context, friendDB *relation.FriendModel, func FriendsDB2Pb( ctx context.Context, - friendsDB []*relation.FriendModel, + friendsDB []*model.Friend, getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error), ) (friendsPb []*sdkws.FriendInfo, err error) { if len(friendsDB) == 0 { @@ -89,7 +89,7 @@ func FriendsDB2Pb( } -func FriendRequestDB2Pb(ctx context.Context, friendRequests []*relation.FriendRequestModel, getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error)) ([]*sdkws.FriendRequest, error) { +func FriendRequestDB2Pb(ctx context.Context, friendRequests []*model.FriendRequest, getUsers func(ctx context.Context, userIDs []string) (map[string]*sdkws.UserInfo, error)) ([]*sdkws.FriendRequest, error) { if len(friendRequests) == 0 { return nil, nil } @@ -134,8 +134,8 @@ func FriendPb2DBMap(friend *sdkws.FriendInfo) map[string]any { val := make(map[string]any) - // Assuming FriendInfo has similar fields to those in FriendModel. - // Add or remove fields based on your actual FriendInfo and FriendModel structures. + // Assuming FriendInfo has similar fields to those in Friend. + // Add or remove fields based on your actual FriendInfo and Friend structures. if friend.FriendUser != nil { if friend.FriendUser.UserID != "" { val["friend_user_id"] = friend.FriendUser.UserID diff --git a/pkg/common/convert/group.go b/pkg/common/convert/group.go index 9b7353cfd..bc2b2f998 100644 --- a/pkg/common/convert/group.go +++ b/pkg/common/convert/group.go @@ -15,14 +15,14 @@ package convert import ( + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" pbgroup "github.com/openimsdk/protocol/group" sdkws "github.com/openimsdk/protocol/sdkws" ) -func Db2PbGroupInfo(m *relation.GroupModel, ownerUserID string, memberCount uint32) *sdkws.GroupInfo { +func Db2PbGroupInfo(m *model.Group, ownerUserID string, memberCount uint32) *sdkws.GroupInfo { return &sdkws.GroupInfo{ GroupID: m.GroupID, GroupName: m.GroupName, @@ -44,8 +44,8 @@ func Db2PbGroupInfo(m *relation.GroupModel, ownerUserID string, memberCount uint } } -func Pb2DbGroupRequest(req *pbgroup.GroupApplicationResponseReq, handleUserID string) *relation.GroupRequestModel { - return &relation.GroupRequestModel{ +func Pb2DbGroupRequest(req *pbgroup.GroupApplicationResponseReq, handleUserID string) *model.GroupRequest { + return &model.GroupRequest{ UserID: req.FromUserID, GroupID: req.GroupID, HandleResult: req.HandleResult, @@ -55,7 +55,7 @@ func Pb2DbGroupRequest(req *pbgroup.GroupApplicationResponseReq, handleUserID st } } -func Db2PbCMSGroup(m *relation.GroupModel, ownerUserID string, ownerUserName string, memberCount uint32) *pbgroup.CMSGroup { +func Db2PbCMSGroup(m *model.Group, ownerUserID string, ownerUserName string, memberCount uint32) *pbgroup.CMSGroup { return &pbgroup.CMSGroup{ GroupInfo: Db2PbGroupInfo(m, ownerUserID, memberCount), GroupOwnerUserID: ownerUserID, @@ -63,7 +63,7 @@ func Db2PbCMSGroup(m *relation.GroupModel, ownerUserID string, ownerUserName str } } -func Db2PbGroupMember(m *relation.GroupMemberModel) *sdkws.GroupMemberFullInfo { +func Db2PbGroupMember(m *model.GroupMember) *sdkws.GroupMemberFullInfo { return &sdkws.GroupMemberFullInfo{ GroupID: m.GroupID, UserID: m.UserID, @@ -80,7 +80,7 @@ func Db2PbGroupMember(m *relation.GroupMemberModel) *sdkws.GroupMemberFullInfo { } } -func Db2PbGroupRequest(m *relation.GroupRequestModel, user *sdkws.PublicUserInfo, group *sdkws.GroupInfo) *sdkws.GroupRequest { +func Db2PbGroupRequest(m *model.GroupRequest, user *sdkws.PublicUserInfo, group *sdkws.GroupInfo) *sdkws.GroupRequest { return &sdkws.GroupRequest{ UserInfo: user, GroupInfo: group, @@ -108,8 +108,8 @@ func Db2PbGroupAbstractInfo( } } -func Pb2DBGroupInfo(m *sdkws.GroupInfo) *relation.GroupModel { - return &relation.GroupModel{ +func Pb2DBGroupInfo(m *sdkws.GroupInfo) *model.Group { + return &model.Group{ GroupID: m.GroupID, GroupName: m.GroupName, Notification: m.Notification, @@ -128,8 +128,8 @@ func Pb2DBGroupInfo(m *sdkws.GroupInfo) *relation.GroupModel { } } -// func Pb2DbGroupMember(m *sdkws.UserInfo) *relation.GroupMemberModel { -// return &relation.GroupMemberModel{ +// func Pb2DbGroupMember(m *sdkws.UserInfo) *relation.GroupMember { +// return &relation.GroupMember{ // UserID: m.UserID, // Nickname: m.Nickname, // FaceURL: m.FaceURL, diff --git a/pkg/common/convert/msg.go b/pkg/common/convert/msg.go index 594a0ffc2..41f6b41f6 100644 --- a/pkg/common/convert/msg.go +++ b/pkg/common/convert/msg.go @@ -15,16 +15,16 @@ package convert import ( - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" ) -func MsgPb2DB(msg *sdkws.MsgData) *relation.MsgDataModel { +func MsgPb2DB(msg *sdkws.MsgData) *model.MsgDataModel { if msg == nil { return nil } - var msgDataModel relation.MsgDataModel + var msgDataModel model.MsgDataModel msgDataModel.SendID = msg.SendID msgDataModel.RecvID = msg.RecvID msgDataModel.GroupID = msg.GroupID @@ -43,7 +43,7 @@ func MsgPb2DB(msg *sdkws.MsgData) *relation.MsgDataModel { msgDataModel.Status = msg.Status msgDataModel.Options = msg.Options if msg.OfflinePushInfo != nil { - msgDataModel.OfflinePush = &relation.OfflinePushModel{ + msgDataModel.OfflinePush = &model.OfflinePushModel{ Title: msg.OfflinePushInfo.Title, Desc: msg.OfflinePushInfo.Desc, Ex: msg.OfflinePushInfo.Ex, @@ -57,7 +57,7 @@ func MsgPb2DB(msg *sdkws.MsgData) *relation.MsgDataModel { return &msgDataModel } -func MsgDB2Pb(msgModel *relation.MsgDataModel) *sdkws.MsgData { +func MsgDB2Pb(msgModel *model.MsgDataModel) *sdkws.MsgData { if msgModel == nil { return nil } diff --git a/pkg/common/convert/user.go b/pkg/common/convert/user.go index a9378e1a0..ccc574f51 100644 --- a/pkg/common/convert/user.go +++ b/pkg/common/convert/user.go @@ -15,13 +15,13 @@ package convert import ( + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/sdkws" ) -func UsersDB2Pb(users []*relationtb.UserModel) []*sdkws.UserInfo { +func UsersDB2Pb(users []*relationtb.User) []*sdkws.UserInfo { result := make([]*sdkws.UserInfo, 0, len(users)) for _, user := range users { userPb := &sdkws.UserInfo{ @@ -38,8 +38,8 @@ func UsersDB2Pb(users []*relationtb.UserModel) []*sdkws.UserInfo { return result } -func UserPb2DB(user *sdkws.UserInfo) *relationtb.UserModel { - return &relationtb.UserModel{ +func UserPb2DB(user *sdkws.UserInfo) *relationtb.User { + return &relationtb.User{ UserID: user.UserID, Nickname: user.Nickname, FaceURL: user.FaceURL, diff --git a/pkg/common/convert/user_test.go b/pkg/common/convert/user_test.go index 88eb812d2..be8137265 100644 --- a/pkg/common/convert/user_test.go +++ b/pkg/common/convert/user_test.go @@ -15,17 +15,16 @@ package convert import ( + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "reflect" "testing" "github.com/openimsdk/protocol/sdkws" - - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" ) func TestUsersDB2Pb(t *testing.T) { type args struct { - users []*relationtb.UserModel + users []*relationtb.User } tests := []struct { name string @@ -50,7 +49,7 @@ func TestUserPb2DB(t *testing.T) { tests := []struct { name string args args - want *relationtb.UserModel + want *relationtb.User }{ // TODO: Add test cases. } diff --git a/pkg/common/db/cache/conversation.go b/pkg/common/db/cache/conversation.go deleted file mode 100644 index bd189f2a9..000000000 --- a/pkg/common/db/cache/conversation.go +++ /dev/null @@ -1,371 +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 cache - -import ( - "context" - "math/big" - "strings" - "time" - - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" - "github.com/openimsdk/tools/log" - "github.com/openimsdk/tools/utils/datautil" - "github.com/openimsdk/tools/utils/encrypt" - "github.com/redis/go-redis/v9" -) - -const ( - // ConversationKey = "CONVERSATION:" - // conversationIDsKey = "CONVERSATION_IDS:" - // conversationIDsHashKey = "CONVERSATION_IDS_HASH:" - // conversationHasReadSeqKey = "CONVERSATION_HAS_READ_SEQ:" - // recvMsgOptKey = "RECV_MSG_OPT:" - // superGroupRecvMsgNotNotifyUserIDsKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS:" - // superGroupRecvMsgNotNotifyUserIDsHashKey = "SUPER_GROUP_RECV_MSG_NOT_NOTIFY_USER_IDS_HASH:" - // conversationNotReceiveMessageUserIDsKey = "CONVERSATION_NOT_RECEIVE_MESSAGE_USER_IDS:". - - conversationExpireTime = time.Second * 60 * 60 * 12 -) - -// arg fn will exec when no data in msgCache. -type ConversationCache interface { - metaCache - NewCache() ConversationCache - // get user's conversationIDs from msgCache - GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) - DelConversationIDs(userIDs ...string) ConversationCache - - GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) - DelUserConversationIDsHash(ownerUserIDs ...string) ConversationCache - - // get one conversation from msgCache - GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationtb.ConversationModel, error) - DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache - DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache - // get one conversation from msgCache - GetConversations(ctx context.Context, ownerUserID string, - conversationIDs []string) ([]*relationtb.ConversationModel, error) - // get one user's all conversations from msgCache - GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) - // get user conversation recv msg from msgCache - GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) - DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache - // get one super group recv msg but do not notification userID list - // GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) - DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache - // get one super group recv msg but do not notification userID list hash - // GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) - DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache - - // GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) - DelUserAllHasReadSeqs(ownerUserID string, conversationIDs ...string) ConversationCache - - GetConversationsByConversationID(ctx context.Context, - conversationIDs []string) ([]*relationtb.ConversationModel, error) - DelConversationByConversationID(conversationIDs ...string) ConversationCache - GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) - DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache -} - -func NewConversationRedis(rdb redis.UniversalClient, localCache *config.LocalCache, opts rockscache.Options, db relationtb.ConversationModelInterface) ConversationCache { - rcClient := rockscache.NewClient(rdb, opts) - mc := NewMetaCacheRedis(rcClient) - c := localCache.Conversation - log.ZDebug(context.Background(), "black local cache init", "Topic", c.Topic, "SlotNum", c.SlotNum, "SlotSize", c.SlotSize, "enable", c.Enable()) - mc.SetTopic(c.Topic) - mc.SetRawRedisClient(rdb) - return &ConversationRedisCache{ - rcClient: rcClient, - metaCache: mc, - conversationDB: db, - expireTime: conversationExpireTime, - } -} - -type ConversationRedisCache struct { - metaCache - rcClient *rockscache.Client - conversationDB relationtb.ConversationModelInterface - expireTime time.Duration -} - -// func NewNewConversationRedis( -// rdb redis.UniversalClient, -// conversationDB *relation.ConversationGorm, -// options rockscache.Options, -// ) ConversationCache { -// rcClient := rockscache.NewClient(rdb, options) -// -// return &ConversationRedisCache{ -// rcClient: rcClient, -// metaCache: NewMetaCacheRedis(rcClient), -// conversationDB: conversationDB, -// expireTime: conversationExpireTime, -// } -//} - -func (c *ConversationRedisCache) NewCache() ConversationCache { - return &ConversationRedisCache{ - rcClient: c.rcClient, - metaCache: c.Copy(), - conversationDB: c.conversationDB, - expireTime: c.expireTime, - } -} - -func (c *ConversationRedisCache) getConversationKey(ownerUserID, conversationID string) string { - return cachekey.GetConversationKey(ownerUserID, conversationID) -} - -func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID string) string { - return cachekey.GetConversationIDsKey(ownerUserID) -} - -func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string { - return cachekey.GetSuperGroupRecvNotNotifyUserIDsKey(groupID) -} - -func (c *ConversationRedisCache) getRecvMsgOptKey(ownerUserID, conversationID string) string { - return cachekey.GetRecvMsgOptKey(ownerUserID, conversationID) -} - -func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string { - return cachekey.GetSuperGroupRecvNotNotifyUserIDsHashKey(groupID) -} - -func (c *ConversationRedisCache) getConversationHasReadSeqKey(ownerUserID, conversationID string) string { - return cachekey.GetConversationHasReadSeqKey(ownerUserID, conversationID) -} - -func (c *ConversationRedisCache) getConversationNotReceiveMessageUserIDsKey(conversationID string) string { - return cachekey.GetConversationNotReceiveMessageUserIDsKey(conversationID) -} - -func (c *ConversationRedisCache) getUserConversationIDsHashKey(ownerUserID string) string { - return cachekey.GetUserConversationIDsHashKey(ownerUserID) -} - -func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { - return getCache(ctx, c.rcClient, c.getConversationIDsKey(ownerUserID), c.expireTime, func(ctx context.Context) ([]string, error) { - return c.conversationDB.FindUserIDAllConversationID(ctx, ownerUserID) - }) -} - -func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string) ConversationCache { - keys := make([]string, 0, len(userIDs)) - for _, userID := range userIDs { - keys = append(keys, c.getConversationIDsKey(userID)) - } - cache := c.NewCache() - cache.AddKeys(keys...) - - return cache -} - -func (c *ConversationRedisCache) GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) { - return getCache( - ctx, - c.rcClient, - c.getUserConversationIDsHashKey(ownerUserID), - c.expireTime, - func(ctx context.Context) (uint64, error) { - conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID) - if err != nil { - return 0, err - } - datautil.Sort(conversationIDs, true) - bi := big.NewInt(0) - bi.SetString(encrypt.Md5(strings.Join(conversationIDs, ";"))[0:8], 16) - return bi.Uint64(), nil - }, - ) -} - -func (c *ConversationRedisCache) DelUserConversationIDsHash(ownerUserIDs ...string) ConversationCache { - keys := make([]string, 0, len(ownerUserIDs)) - for _, ownerUserID := range ownerUserIDs { - keys = append(keys, c.getUserConversationIDsHashKey(ownerUserID)) - } - cache := c.NewCache() - cache.AddKeys(keys...) - - return cache -} - -func (c *ConversationRedisCache) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationtb.ConversationModel, error) { - return getCache(ctx, c.rcClient, c.getConversationKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (*relationtb.ConversationModel, error) { - return c.conversationDB.Take(ctx, ownerUserID, conversationID) - }) -} - -func (c *ConversationRedisCache) DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache { - keys := make([]string, 0, len(conversationIDs)) - for _, conversationID := range conversationIDs { - keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) - } - cache := c.NewCache() - cache.AddKeys(keys...) - - return cache -} - -// func (c *ConversationRedisCache) getConversationIndex(convsation *relationtb.ConversationModel, keys []string) (int, error) { -// key := c.getConversationKey(convsation.OwnerUserID, convsation.ConversationID) -// for _i, _key := range keys { -// if _key == key { -// return _i, nil -// } -// } - -// return 0, errs.New("not found key:" + key + " in keys") -// } - -func (c *ConversationRedisCache) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) { - // var keys []string - // for _, conversarionID := range conversationIDs { - // keys = append(keys, c.getConversationKey(ownerUserID, conversarionID)) - //} - // return batchGetCache( - // ctx, - // c.rcClient, - // keys, - // c.expireTime, - // c.getConversationIndex, - // func(ctx context.Context) ([]*relationtb.ConversationModel, error) { - // return c.conversationDB.Find(ctx, ownerUserID, conversationIDs) - // }, - //) - return batchGetCache2(ctx, c.rcClient, c.expireTime, conversationIDs, func(conversationID string) string { - return c.getConversationKey(ownerUserID, conversationID) - }, func(ctx context.Context, conversationID string) (*relationtb.ConversationModel, error) { - return c.conversationDB.Take(ctx, ownerUserID, conversationID) - }) -} - -func (c *ConversationRedisCache) GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) { - conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID) - if err != nil { - return nil, err - } - // var keys []string - // for _, conversarionID := range conversationIDs { - // keys = append(keys, c.getConversationKey(ownerUserID, conversarionID)) - //} - // return batchGetCache( - // ctx, - // c.rcClient, - // keys, - // c.expireTime, - // c.getConversationIndex, - // func(ctx context.Context) ([]*relationtb.ConversationModel, error) { - // return c.conversationDB.FindUserIDAllConversations(ctx, ownerUserID) - // }, - //) - return c.GetConversations(ctx, ownerUserID, conversationIDs) -} - -func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) { - return getCache(ctx, c.rcClient, c.getRecvMsgOptKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (opt int, err error) { - return c.conversationDB.GetUserRecvMsgOpt(ctx, ownerUserID, conversationID) - }) -} - -// func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) { -// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsKey(groupID), c.expireTime, func(ctx context.Context) (userIDs []string, err error) { -// return c.conversationDB.FindSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) -// }) -//} - -func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache { - keys := make([]string, 0, len(ownerUserIDs)) - for _, ownerUserID := range ownerUserIDs { - keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) - } - cache := c.NewCache() - cache.AddKeys(keys...) - - return cache -} - -func (c *ConversationRedisCache) DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache { - cache := c.NewCache() - cache.AddKeys(c.getRecvMsgOptKey(ownerUserID, conversationID)) - - return cache -} - -func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache { - cache := c.NewCache() - cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsKey(groupID)) - - return cache -} - -// func (c *ConversationRedisCache) GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) { -// return getCache(ctx, c.rcClient, c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID), c.expireTime, func(ctx context.Context) (hash uint64, err error) { -// userIDs, err := c.GetSuperGroupRecvMsgNotNotifyUserIDs(ctx, groupID) -// if err != nil { -// return 0, err -// } -// utils.Sort(userIDs, true) -// bi := big.NewInt(0) -// bi.SetString(utils.Md5(strings.Join(userIDs, ";"))[0:8], 16) -// return bi.Uint64(), nil -// }, -// ) -//} - -func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache { - cache := c.NewCache() - cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID)) - - return cache -} - -func (c *ConversationRedisCache) DelUserAllHasReadSeqs(ownerUserID string, conversationIDs ...string) ConversationCache { - cache := c.NewCache() - for _, conversationID := range conversationIDs { - cache.AddKeys(c.getConversationHasReadSeqKey(ownerUserID, conversationID)) - } - - return cache -} - -func (c *ConversationRedisCache) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) { - panic("implement me") -} - -func (c *ConversationRedisCache) DelConversationByConversationID(conversationIDs ...string) ConversationCache { - panic("implement me") -} - -func (c *ConversationRedisCache) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { - return getCache(ctx, c.rcClient, c.getConversationNotReceiveMessageUserIDsKey(conversationID), c.expireTime, func(ctx context.Context) ([]string, error) { - return c.conversationDB.GetConversationNotReceiveMessageUserIDs(ctx, conversationID) - }) -} - -func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache { - cache := c.NewCache() - for _, conversationID := range conversationIDs { - cache.AddKeys(c.getConversationNotReceiveMessageUserIDsKey(conversationID)) - } - - return cache -} diff --git a/pkg/common/db/cache/meta_cache.go b/pkg/common/db/cache/meta_cache.go deleted file mode 100644 index e633e4fbd..000000000 --- a/pkg/common/db/cache/meta_cache.go +++ /dev/null @@ -1,284 +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 cache - -import ( - "context" - "encoding/json" - "fmt" - "time" - - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/tools/errs" - "github.com/openimsdk/tools/log" - "github.com/openimsdk/tools/mw/specialerror" - "github.com/openimsdk/tools/utils/datautil" - "github.com/redis/go-redis/v9" -) - -const ( - scanCount = 3000 - maxRetryTimes = 5 - retryInterval = time.Millisecond * 100 -) - -var errIndex = errs.New("err index") - -type metaCache interface { - ExecDel(ctx context.Context, distinct ...bool) error - // delete key rapid - DelKey(ctx context.Context, key string) error - AddKeys(keys ...string) - ClearKeys() - GetPreDelKeys() []string - SetTopic(topic string) - SetRawRedisClient(cli redis.UniversalClient) - Copy() metaCache -} - -func NewMetaCacheRedis(rcClient *rockscache.Client, keys ...string) metaCache { - return &metaCacheRedis{rcClient: rcClient, keys: keys, maxRetryTimes: maxRetryTimes, retryInterval: retryInterval} -} - -type metaCacheRedis struct { - topic string - rcClient *rockscache.Client - keys []string - maxRetryTimes int - retryInterval time.Duration - redisClient redis.UniversalClient -} - -func (m *metaCacheRedis) Copy() metaCache { - var keys []string - if len(m.keys) > 0 { - keys = make([]string, 0, len(m.keys)*2) - keys = append(keys, m.keys...) - } - return &metaCacheRedis{ - topic: m.topic, - rcClient: m.rcClient, - keys: keys, - maxRetryTimes: m.maxRetryTimes, - retryInterval: m.retryInterval, - redisClient: m.redisClient, - } -} - -func (m *metaCacheRedis) SetTopic(topic string) { - m.topic = topic -} - -func (m *metaCacheRedis) SetRawRedisClient(cli redis.UniversalClient) { - m.redisClient = cli -} - -func (m *metaCacheRedis) ExecDel(ctx context.Context, distinct ...bool) error { - if len(distinct) > 0 && distinct[0] { - m.keys = datautil.Distinct(m.keys) - } - if len(m.keys) > 0 { - log.ZDebug(ctx, "delete cache", "topic", m.topic, "keys", m.keys) - for _, key := range m.keys { - for i := 0; i < m.maxRetryTimes; i++ { - if err := m.rcClient.TagAsDeleted(key); err != nil { - log.ZError(ctx, "delete cache failed", err, "key", key) - time.Sleep(m.retryInterval) - continue - } - break - } - } - if pk := getPublishKey(m.topic, m.keys); len(pk) > 0 { - data, err := json.Marshal(pk) - if err != nil { - log.ZError(ctx, "keys json marshal failed", err, "topic", m.topic, "keys", pk) - } else { - if err := m.redisClient.Publish(ctx, m.topic, string(data)).Err(); err != nil { - log.ZError(ctx, "redis publish cache delete error", err, "topic", m.topic, "keys", pk) - } - } - } - } - return nil -} - -func (m *metaCacheRedis) DelKey(ctx context.Context, key string) error { - return m.rcClient.TagAsDeleted2(ctx, key) -} - -func (m *metaCacheRedis) AddKeys(keys ...string) { - m.keys = append(m.keys, keys...) -} - -func (m *metaCacheRedis) ClearKeys() { - m.keys = []string{} -} - -func (m *metaCacheRedis) GetPreDelKeys() []string { - return m.keys -} - -func GetDefaultOpt() rockscache.Options { - opts := rockscache.NewDefaultOptions() - opts.StrongConsistency = true - opts.RandomExpireAdjustment = 0.2 - - return opts -} - -func getCache[T any](ctx context.Context, rcClient *rockscache.Client, key string, expire time.Duration, fn func(ctx context.Context) (T, error)) (T, error) { - var t T - var write bool - v, err := rcClient.Fetch2(ctx, key, expire, func() (s string, err error) { - t, err = fn(ctx) - if err != nil { - return "", err - } - bs, err := json.Marshal(t) - if err != nil { - return "", errs.WrapMsg(err, "marshal failed") - } - write = true - - return string(bs), nil - }) - if err != nil { - return t, errs.Wrap(err) - } - if write { - return t, nil - } - if v == "" { - return t, errs.ErrRecordNotFound.WrapMsg("cache is not found") - } - err = json.Unmarshal([]byte(v), &t) - if err != nil { - errInfo := fmt.Sprintf("cache json.Unmarshal failed, key:%s, value:%s, expire:%s", key, v, expire) - return t, errs.WrapMsg(err, errInfo) - } - - return t, nil -} - -// func batchGetCache[T any](ctx context.Context, rcClient *rockscache.Client, keys []string, expire time.Duration, keyIndexFn func(t T, keys []string) (int, error), fn func(ctx context.Context) ([]T, -// error)) ([]T, error) { -// batchMap, err := rcClient.FetchBatch2(ctx, keys, expire, func(idxs []int) (m map[int]string, err error) { -// values := make(map[int]string) -// tArrays, err := fn(ctx) -// if err != nil { -// return nil, err -// } -// for _, v := range tArrays { -// index, err := keyIndexFn(v, keys) -// if err != nil { -// continue -// } -// bs, err := json.Marshal(v) -// if err != nil { -// return nil, utils.Wrap(err, "marshal failed") -// } -// values[index] = string(bs) -// } -// return values, nil -// }) -// if err != nil { -// return nil, err -// } -// var tArrays []T -// for _, v := range batchMap { -// if v != "" { -// var t T -// err = json.Unmarshal([]byte(v), &t) -// if err != nil { -// return nil, utils.Wrap(err, "unmarshal failed") -// } -// tArrays = append(tArrays, t) -// } -// } -// return tArrays, nil -//} - -func batchGetCache2[T any, K comparable]( - ctx context.Context, - rcClient *rockscache.Client, - expire time.Duration, - keys []K, - keyFn func(key K) string, - fns func(ctx context.Context, key K) (T, error), -) ([]T, error) { - if len(keys) == 0 { - return nil, nil - } - res := make([]T, 0, len(keys)) - for _, key := range keys { - val, err := getCache(ctx, rcClient, keyFn(key), expire, func(ctx context.Context) (T, error) { - return fns(ctx, key) - }) - if err != nil { - if errs.ErrRecordNotFound.Is(specialerror.ErrCode(errs.Unwrap(err))) { - continue - } - return nil, errs.Wrap(err) - } - res = append(res, val) - } - - return res, nil -} - -// func batchGetCacheMap[T any]( -// ctx context.Context, -// rcClient *rockscache.Client, -// keys, originKeys []string, -// expire time.Duration, -// keyIndexFn func(s string, keys []string) (int, error), -// fn func(ctx context.Context) (map[string]T, error), -// ) (map[string]T, error) { -// batchMap, err := rcClient.FetchBatch2(ctx, keys, expire, func(idxs []int) (m map[int]string, err error) { -// tArrays, err := fn(ctx) -// if err != nil { -// return nil, err -// } -// values := make(map[int]string) -// for k, v := range tArrays { -// index, err := keyIndexFn(k, originKeys) -// if err != nil { -// continue -// } -// bs, err := json.Marshal(v) -// if err != nil { -// return nil, utils.Wrap(err, "marshal failed") -// } -// values[index] = string(bs) -// } -// return values, nil -// }) -// if err != nil { -// return nil, err -// } -// tMap := make(map[string]T) -// for i, v := range batchMap { -// if v != "" { -// var t T -// err = json.Unmarshal([]byte(v), &t) -// if err != nil { -// return nil, utils.Wrap(err, "unmarshal failed") -// } -// tMap[originKeys[i]] = t -// } -// } -// return tMap, nil -//} diff --git a/pkg/common/db/cache/third.go b/pkg/common/db/cache/third.go deleted file mode 100644 index d2900a32d..000000000 --- a/pkg/common/db/cache/third.go +++ /dev/null @@ -1,85 +0,0 @@ -package cache - -import ( - "context" - "github.com/openimsdk/tools/errs" - "github.com/redis/go-redis/v9" - "strconv" - "time" -) - -type ThirdCache interface { - SetFcmToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) (err error) - GetFcmToken(ctx context.Context, account string, platformID int) (string, error) - DelFcmToken(ctx context.Context, account string, platformID int) error - IncrUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) - SetUserBadgeUnreadCountSum(ctx context.Context, userID string, value int) error - GetUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) - SetGetuiToken(ctx context.Context, token string, expireTime int64) error - GetGetuiToken(ctx context.Context) (string, error) - SetGetuiTaskID(ctx context.Context, taskID string, expireTime int64) error - GetGetuiTaskID(ctx context.Context) (string, error) -} - -func NewThirdCache(rdb redis.UniversalClient) ThirdCache { - return &thirdCache{rdb: rdb} -} - -type thirdCache struct { - rdb redis.UniversalClient -} - -func (c *thirdCache) SetFcmToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) (err error) { - return errs.Wrap(c.rdb.Set(ctx, FCM_TOKEN+account+":"+strconv.Itoa(platformID), fcmToken, time.Duration(expireTime)*time.Second).Err()) -} - -func (c *thirdCache) GetFcmToken(ctx context.Context, account string, platformID int) (string, error) { - val, err := c.rdb.Get(ctx, FCM_TOKEN+account+":"+strconv.Itoa(platformID)).Result() - if err != nil { - return "", errs.Wrap(err) - } - return val, nil -} - -func (c *thirdCache) DelFcmToken(ctx context.Context, account string, platformID int) error { - return errs.Wrap(c.rdb.Del(ctx, FCM_TOKEN+account+":"+strconv.Itoa(platformID)).Err()) -} - -func (c *thirdCache) IncrUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) { - seq, err := c.rdb.Incr(ctx, userBadgeUnreadCountSum+userID).Result() - - return int(seq), errs.Wrap(err) -} - -func (c *thirdCache) SetUserBadgeUnreadCountSum(ctx context.Context, userID string, value int) error { - return errs.Wrap(c.rdb.Set(ctx, userBadgeUnreadCountSum+userID, value, 0).Err()) -} - -func (c *thirdCache) GetUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) { - val, err := c.rdb.Get(ctx, userBadgeUnreadCountSum+userID).Int() - return val, errs.Wrap(err) -} - -func (c *thirdCache) SetGetuiToken(ctx context.Context, token string, expireTime int64) error { - return errs.Wrap(c.rdb.Set(ctx, getuiToken, token, time.Duration(expireTime)*time.Second).Err()) -} - -func (c *thirdCache) GetGetuiToken(ctx context.Context) (string, error) { - val, err := c.rdb.Get(ctx, getuiToken).Result() - if err != nil { - return "", errs.Wrap(err) - } - return val, nil -} - -func (c *thirdCache) SetGetuiTaskID(ctx context.Context, taskID string, expireTime int64) error { - return errs.Wrap(c.rdb.Set(ctx, getuiTaskID, taskID, time.Duration(expireTime)*time.Second).Err()) -} - -func (c *thirdCache) GetGetuiTaskID(ctx context.Context) (string, error) { - val, err := c.rdb.Get(ctx, getuiTaskID).Result() - if err != nil { - return "", errs.Wrap(err) - } - return val, nil -} diff --git a/pkg/common/db/table/relation/doc.go b/pkg/common/db/table/relation/doc.go deleted file mode 100644 index c711dec70..000000000 --- a/pkg/common/db/table/relation/doc.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright © 2024 OpenIM. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package relation // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" diff --git a/pkg/common/storage/cache/batch_handler.go b/pkg/common/storage/cache/batch_handler.go new file mode 100644 index 000000000..84174258a --- /dev/null +++ b/pkg/common/storage/cache/batch_handler.go @@ -0,0 +1,17 @@ +package cache + +import ( + "context" +) + +// BatchDeleter interface defines a set of methods for batch deleting cache and publishing deletion information. +type BatchDeleter interface { + //ChainExecDel method is used for chain calls and must call Clone to prevent memory pollution. + ChainExecDel(ctx context.Context) error + //ExecDelWithKeys method directly takes keys for deletion. + ExecDelWithKeys(ctx context.Context, keys []string) error + //Clone method creates a copy of the BatchDeleter to avoid modifying the original object. + Clone() BatchDeleter + //AddKeys method adds keys to be deleted. + AddKeys(keys ...string) +} diff --git a/pkg/common/storage/cache/black.go b/pkg/common/storage/cache/black.go new file mode 100644 index 000000000..515ce3c12 --- /dev/null +++ b/pkg/common/storage/cache/black.go @@ -0,0 +1,27 @@ +// 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 cache + +import ( + "context" +) + +type BlackCache interface { + BatchDeleter + CloneBlackCache() BlackCache + GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) + // del user's blackIDs msgCache, exec when a user's black list changed + DelBlackIDs(ctx context.Context, userID string) BlackCache +} diff --git a/pkg/common/cachekey/black.go b/pkg/common/storage/cache/cachekey/black.go similarity index 100% rename from pkg/common/cachekey/black.go rename to pkg/common/storage/cache/cachekey/black.go diff --git a/pkg/common/cachekey/conversation.go b/pkg/common/storage/cache/cachekey/conversation.go similarity index 100% rename from pkg/common/cachekey/conversation.go rename to pkg/common/storage/cache/cachekey/conversation.go diff --git a/pkg/common/cachekey/doc.go b/pkg/common/storage/cache/cachekey/doc.go similarity index 95% rename from pkg/common/cachekey/doc.go rename to pkg/common/storage/cache/cachekey/doc.go index 4975537ec..caeda4cea 100644 --- a/pkg/common/cachekey/doc.go +++ b/pkg/common/storage/cache/cachekey/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cachekey // import "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" +package cachekey // import "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cachekey" diff --git a/pkg/common/cachekey/friend.go b/pkg/common/storage/cache/cachekey/friend.go similarity index 100% rename from pkg/common/cachekey/friend.go rename to pkg/common/storage/cache/cachekey/friend.go diff --git a/pkg/common/cachekey/group.go b/pkg/common/storage/cache/cachekey/group.go similarity index 100% rename from pkg/common/cachekey/group.go rename to pkg/common/storage/cache/cachekey/group.go diff --git a/pkg/common/storage/cache/cachekey/msg.go b/pkg/common/storage/cache/cachekey/msg.go new file mode 100644 index 000000000..d1e8eeb7b --- /dev/null +++ b/pkg/common/storage/cache/cachekey/msg.go @@ -0,0 +1,70 @@ +// Copyright © 2024 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 cachekey + +import ( + "github.com/openimsdk/protocol/constant" + "strconv" +) + +const ( + messageCache = "MESSAGE_CACHE:" + messageDelUserList = "MESSAGE_DEL_USER_LIST:" + userDelMessagesList = "USER_DEL_MESSAGES_LIST:" + sendMsgFailedFlag = "SEND_MSG_FAILED_FLAG:" + exTypeKeyLocker = "EX_LOCK:" + reactionExSingle = "EX_SINGLE_" + reactionWriteGroup = "EX_GROUP_" + reactionReadGroup = "EX_SUPER_GROUP_" + reactionNotification = "EX_NOTIFICATION_" +) + +func GetAllMessageCacheKey(conversationID string) string { + return messageCache + conversationID + "_*" +} + +func GetMessageCacheKey(conversationID string, seq int64) string { + return messageCache + conversationID + "_" + strconv.Itoa(int(seq)) +} + +func GetMessageDelUserListKey(conversationID string, seq int64) string { + return messageDelUserList + conversationID + ":" + strconv.Itoa(int(seq)) +} + +func GetUserDelListKey(conversationID, userID string) string { + return userDelMessagesList + conversationID + ":" + userID +} + +func GetMessageReactionExKey(clientMsgID string, sessionType int32) string { + switch sessionType { + case constant.SingleChatType: + return reactionExSingle + clientMsgID + case constant.WriteGroupChatType: + return reactionWriteGroup + clientMsgID + case constant.ReadGroupChatType: + return reactionReadGroup + clientMsgID + case constant.NotificationChatType: + return reactionNotification + clientMsgID + } + + return "" +} +func GetLockMessageTypeKey(clientMsgID string, TypeKey string) string { + return exTypeKeyLocker + clientMsgID + "_" + TypeKey +} + +func GetSendMsgKey(id string) string { + return sendMsgFailedFlag + id +} diff --git a/pkg/common/storage/cache/cachekey/s3.go b/pkg/common/storage/cache/cachekey/s3.go new file mode 100644 index 000000000..5c9540b9e --- /dev/null +++ b/pkg/common/storage/cache/cachekey/s3.go @@ -0,0 +1,40 @@ +// Copyright © 2024 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 cachekey + +import "strconv" + +const ( + object = "OBJECT:" + s3 = "S3:" + minioImageInfo = "MINIO:IMAGE:" + minioThumbnail = "MINIO:THUMBNAIL:" +) + +func GetObjectKey(engine string, name string) string { + return object + engine + ":" + name +} + +func GetS3Key(engine string, name string) string { + return s3 + engine + ":" + name +} + +func GetObjectImageInfoKey(key string) string { + return minioImageInfo + key +} + +func GetMinioImageThumbnailKey(key string, format string, width int, height int) string { + return minioThumbnail + format + ":w" + strconv.Itoa(width) + ":h" + strconv.Itoa(height) + ":" + key +} diff --git a/pkg/common/storage/cache/cachekey/seq.go b/pkg/common/storage/cache/cachekey/seq.go new file mode 100644 index 000000000..3f0ce98a4 --- /dev/null +++ b/pkg/common/storage/cache/cachekey/seq.go @@ -0,0 +1,38 @@ +// Copyright © 2024 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 cachekey + +const ( + maxSeq = "MAX_SEQ:" + minSeq = "MIN_SEQ:" + conversationUserMinSeq = "CON_USER_MIN_SEQ:" + hasReadSeq = "HAS_READ_SEQ:" +) + +func GetMaxSeqKey(conversationID string) string { + return maxSeq + conversationID +} + +func GetMinSeqKey(conversationID string) string { + return minSeq + conversationID +} + +func GetHasReadSeqKey(conversationID string, userID string) string { + return hasReadSeq + userID + ":" + conversationID +} + +func GetConversationUserMinSeqKey(conversationID, userID string) string { + return conversationUserMinSeq + conversationID + "u:" + userID +} diff --git a/pkg/common/storage/cache/cachekey/third.go b/pkg/common/storage/cache/cachekey/third.go new file mode 100644 index 000000000..469900c34 --- /dev/null +++ b/pkg/common/storage/cache/cachekey/third.go @@ -0,0 +1,41 @@ +// Copyright © 2024 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 cachekey + +import ( + "strconv" +) + +const ( + getuiToken = "GETUI_TOKEN" + getuiTaskID = "GETUI_TASK_ID" + fmcToken = "FCM_TOKEN:" + userBadgeUnreadCountSum = "USER_BADGE_UNREAD_COUNT_SUM:" +) + +func GetFcmAccountTokenKey(account string, platformID int) string { + return fmcToken + account + ":" + strconv.Itoa(platformID) +} + +func GetUserBadgeUnreadCountSumKey(userID string) string { + return userBadgeUnreadCountSum + userID +} + +func GetGetuiTokenKey() string { + return getuiToken +} +func GetGetuiTaskIDKey() string { + return getuiTaskID +} diff --git a/pkg/common/cachekey/token.go b/pkg/common/storage/cache/cachekey/token.go similarity index 100% rename from pkg/common/cachekey/token.go rename to pkg/common/storage/cache/cachekey/token.go diff --git a/pkg/common/cachekey/user.go b/pkg/common/storage/cache/cachekey/user.go similarity index 87% rename from pkg/common/cachekey/user.go rename to pkg/common/storage/cache/cachekey/user.go index 473ca1b12..7d06d4f75 100644 --- a/pkg/common/cachekey/user.go +++ b/pkg/common/storage/cache/cachekey/user.go @@ -17,6 +17,7 @@ package cachekey const ( UserInfoKey = "USER_INFO:" UserGlobalRecvMsgOptKey = "USER_GLOBAL_RECV_MSG_OPT_KEY:" + olineStatusKey = "ONLINE_STATUS:" ) func GetUserInfoKey(userID string) string { @@ -26,3 +27,7 @@ func GetUserInfoKey(userID string) string { func GetUserGlobalRecvMsgOptKey(userID string) string { return UserGlobalRecvMsgOptKey + userID } + +func GetOnlineStatusKey(modKey string) string { + return olineStatusKey + modKey +} diff --git a/pkg/common/storage/cache/conversation.go b/pkg/common/storage/cache/conversation.go new file mode 100644 index 000000000..bf85af0c5 --- /dev/null +++ b/pkg/common/storage/cache/conversation.go @@ -0,0 +1,60 @@ +// 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 cache + +import ( + "context" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" +) + +// arg fn will exec when no data in msgCache. +type ConversationCache interface { + BatchDeleter + CloneConversationCache() ConversationCache + // get user's conversationIDs from msgCache + GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) + DelConversationIDs(userIDs ...string) ConversationCache + + GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) + DelUserConversationIDsHash(ownerUserIDs ...string) ConversationCache + + // get one conversation from msgCache + GetConversation(ctx context.Context, ownerUserID, conversationID string) (*relationtb.Conversation, error) + DelConversations(ownerUserID string, conversationIDs ...string) ConversationCache + DelUsersConversation(conversationID string, ownerUserIDs ...string) ConversationCache + // get one conversation from msgCache + GetConversations(ctx context.Context, ownerUserID string, + conversationIDs []string) ([]*relationtb.Conversation, error) + // get one user's all conversations from msgCache + GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*relationtb.Conversation, error) + // get user conversation recv msg from msgCache + GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) + DelUserRecvMsgOpt(ownerUserID, conversationID string) ConversationCache + // get one super group recv msg but do not notification userID list + // GetSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) (userIDs []string, err error) + DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) ConversationCache + // get one super group recv msg but do not notification userID list hash + // GetSuperGroupRecvMsgNotNotifyUserIDsHash(ctx context.Context, groupID string) (hash uint64, err error) + DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) ConversationCache + + // GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) + DelUserAllHasReadSeqs(ownerUserID string, conversationIDs ...string) ConversationCache + + GetConversationsByConversationID(ctx context.Context, + conversationIDs []string) ([]*relationtb.Conversation, error) + DelConversationByConversationID(conversationIDs ...string) ConversationCache + GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) + DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) ConversationCache +} diff --git a/pkg/common/db/cache/doc.go b/pkg/common/storage/cache/doc.go similarity index 96% rename from pkg/common/db/cache/doc.go rename to pkg/common/storage/cache/doc.go index a5c237249..c74bc75c0 100644 --- a/pkg/common/db/cache/doc.go +++ b/pkg/common/storage/cache/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" +package cache // import "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" diff --git a/pkg/common/storage/cache/friend.go b/pkg/common/storage/cache/friend.go new file mode 100644 index 000000000..acff829f8 --- /dev/null +++ b/pkg/common/storage/cache/friend.go @@ -0,0 +1,35 @@ +// 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 cache + +import ( + "context" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" +) + +// FriendCache is an interface for caching friend-related data. +type FriendCache interface { + BatchDeleter + CloneFriendCache() FriendCache + GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) + // Called when friendID list changed + DelFriendIDs(ownerUserID ...string) FriendCache + // Get single friendInfo from the cache + GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.Friend, err error) + // Delete friend when friend info changed + DelFriend(ownerUserID, friendUserID string) FriendCache + // Delete friends when friends' info changed + DelFriends(ownerUserID string, friendUserIDs []string) FriendCache +} diff --git a/pkg/common/storage/cache/group.go b/pkg/common/storage/cache/group.go new file mode 100644 index 000000000..53e2cd1c7 --- /dev/null +++ b/pkg/common/storage/cache/group.go @@ -0,0 +1,62 @@ +// 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 cache + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/common" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" +) + +type GroupHash interface { + GetGroupHash(ctx context.Context, groupID string) (uint64, error) +} + +type GroupCache interface { + BatchDeleter + CloneGroupCache() GroupCache + GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*model.Group, err error) + GetGroupInfo(ctx context.Context, groupID string) (group *model.Group, err error) + DelGroupsInfo(groupIDs ...string) GroupCache + + GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) + GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*common.GroupSimpleUserID, error) + DelGroupMembersHash(groupID string) GroupCache + + GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) + GetGroupsMemberIDs(ctx context.Context, groupIDs []string) (groupMemberIDs map[string][]string, err error) + + DelGroupMemberIDs(groupID string) GroupCache + + GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) + DelJoinedGroupID(userID ...string) GroupCache + + GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *model.GroupMember, err error) + GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*model.GroupMember, err error) + GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*model.GroupMember, err error) + GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*model.GroupMember, err error) + FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*model.GroupMember, error) + + GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) + GetGroupOwner(ctx context.Context, groupID string) (*model.GroupMember, error) + GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*model.GroupMember, error) + DelGroupRoleLevel(groupID string, roleLevel []int32) GroupCache + DelGroupAllRoleLevel(groupID string) GroupCache + DelGroupMembersInfo(groupID string, userID ...string) GroupCache + GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*model.GroupMember, error) + GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*model.GroupMember, error) + GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error) + DelGroupsMemberNum(groupID ...string) GroupCache +} diff --git a/pkg/common/storage/cache/msg.go b/pkg/common/storage/cache/msg.go new file mode 100644 index 000000000..0adbb3572 --- /dev/null +++ b/pkg/common/storage/cache/msg.go @@ -0,0 +1,43 @@ +// 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 cache + +import ( + "context" + "time" + + "github.com/openimsdk/protocol/sdkws" +) + +type MsgCache interface { + GetMessagesBySeq(ctx context.Context, conversationID string, seqs []int64) (seqMsg []*sdkws.MsgData, failedSeqList []int64, err error) + SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error) + UserDeleteMsgs(ctx context.Context, conversationID string, seqs []int64, userID string) error + DelUserDeleteMsgsList(ctx context.Context, conversationID string, seqs []int64) + DeleteMessages(ctx context.Context, conversationID string, seqs []int64) error + GetUserDelList(ctx context.Context, userID, conversationID string) (seqs []int64, err error) + CleanUpOneConversationAllMsg(ctx context.Context, conversationID string) error + DelMsgFromCache(ctx context.Context, userID string, seqList []int64) error + SetSendMsgStatus(ctx context.Context, id string, status int32) error + GetSendMsgStatus(ctx context.Context, id string) (int32, error) + JudgeMessageReactionExist(ctx context.Context, clientMsgID string, sessionType int32) (bool, error) + GetOneMessageAllReactionList(ctx context.Context, clientMsgID string, sessionType int32) (map[string]string, error) + DeleteOneMessageKey(ctx context.Context, clientMsgID string, sessionType int32, subKey string) error + SetMessageReactionExpire(ctx context.Context, clientMsgID string, sessionType int32, expiration time.Duration) (bool, error) + GetMessageTypeKeyValue(ctx context.Context, clientMsgID string, sessionType int32, typeKey string) (string, error) + SetMessageTypeKeyValue(ctx context.Context, clientMsgID string, sessionType int32, typeKey, value string) error + LockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error + UnLockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error +} diff --git a/pkg/common/storage/cache/redis/batch_handler.go b/pkg/common/storage/cache/redis/batch_handler.go new file mode 100644 index 000000000..b68d8f86d --- /dev/null +++ b/pkg/common/storage/cache/redis/batch_handler.go @@ -0,0 +1,211 @@ +// 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 redis + +import ( + "context" + "encoding/json" + "fmt" + "github.com/dtm-labs/rockscache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/localcache" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/mw/specialerror" + "github.com/openimsdk/tools/utils/datautil" + "github.com/redis/go-redis/v9" + "time" +) + +// BatchDeleterRedis is a concrete implementation of the BatchDeleter interface based on Redis and RocksCache. +type BatchDeleterRedis struct { + redisClient redis.UniversalClient + keys []string + rocksClient *rockscache.Client + redisPubTopics []string +} + +// NewBatchDeleterRedis creates a new BatchDeleterRedis instance. +func NewBatchDeleterRedis(redisClient redis.UniversalClient, options *rockscache.Options, redisPubTopics []string) *BatchDeleterRedis { + return &BatchDeleterRedis{ + redisClient: redisClient, + rocksClient: rockscache.NewClient(redisClient, *options), + redisPubTopics: redisPubTopics, + } +} + +// ExecDelWithKeys directly takes keys for batch deletion and publishes deletion information. +func (c *BatchDeleterRedis) ExecDelWithKeys(ctx context.Context, keys []string) error { + distinctKeys := datautil.Distinct(keys) + return c.execDel(ctx, distinctKeys) +} + +// ChainExecDel is used for chain calls for batch deletion. It must call Clone to prevent memory pollution. +func (c *BatchDeleterRedis) ChainExecDel(ctx context.Context) error { + distinctKeys := datautil.Distinct(c.keys) + return c.execDel(ctx, distinctKeys) +} + +// execDel performs batch deletion and publishes the keys that have been deleted to update the local cache information of other nodes. +func (c *BatchDeleterRedis) execDel(ctx context.Context, keys []string) error { + if len(keys) > 0 { + log.ZDebug(ctx, "delete cache", "topic", c.redisPubTopics, "keys", keys) + slotMapKeys, err := groupKeysBySlot(ctx, c.redisClient, keys) + if err != nil { + return err + } + // Batch delete keys + for slot, singleSlotKeys := range slotMapKeys { + if err := c.rocksClient.TagAsDeletedBatch2(ctx, singleSlotKeys); err != nil { + log.ZWarn(ctx, "Batch delete cache failed", err, "slot", slot, "keys", singleSlotKeys) + continue + } + } + // Publish the keys that have been deleted to Redis to update the local cache information of other nodes + if len(c.redisPubTopics) > 0 && len(keys) > 0 { + keysByTopic := localcache.GetPublishKeysByTopic(c.redisPubTopics, keys) + for topic, keys := range keysByTopic { + if len(keys) > 0 { + data, err := json.Marshal(keys) + if err != nil { + log.ZWarn(ctx, "keys json marshal failed", err, "topic", topic, "keys", keys) + } else { + if err := c.redisClient.Publish(ctx, topic, string(data)).Err(); err != nil { + log.ZWarn(ctx, "redis publish cache delete error", err, "topic", topic, "keys", keys) + } + } + } + } + } + } + return nil +} + +// Clone creates a copy of BatchDeleterRedis for chain calls to prevent memory pollution. +func (c *BatchDeleterRedis) Clone() cache.BatchDeleter { + return &BatchDeleterRedis{ + redisClient: c.redisClient, + keys: c.keys, + rocksClient: c.rocksClient, + redisPubTopics: c.redisPubTopics, + } +} + +// AddKeys adds keys to be deleted. +func (c *BatchDeleterRedis) AddKeys(keys ...string) { + c.keys = append(c.keys, keys...) +} + +// GetRocksCacheOptions returns the default configuration options for RocksCache. +func GetRocksCacheOptions() *rockscache.Options { + opts := rockscache.NewDefaultOptions() + opts.StrongConsistency = true + opts.RandomExpireAdjustment = 0.2 + + return &opts +} + +// groupKeysBySlot groups keys by their Redis cluster hash slots. +func groupKeysBySlot(ctx context.Context, redisClient redis.UniversalClient, keys []string) (map[int64][]string, error) { + slots := make(map[int64][]string) + clusterClient, isCluster := redisClient.(*redis.ClusterClient) + if isCluster { + pipe := clusterClient.Pipeline() + cmds := make([]*redis.IntCmd, len(keys)) + for i, key := range keys { + cmds[i] = pipe.ClusterKeySlot(ctx, key) + } + _, err := pipe.Exec(ctx) + if err != nil { + return nil, errs.WrapMsg(err, "get slot err") + } + + for i, cmd := range cmds { + slot, err := cmd.Result() + if err != nil { + log.ZWarn(ctx, "some key get slot err", err, "key", keys[i]) + continue + } + slots[slot] = append(slots[slot], keys[i]) + } + } else { + // If not a cluster client, put all keys in the same slot (0) + slots[0] = keys + } + + return slots, nil +} + +func getCache[T any](ctx context.Context, rcClient *rockscache.Client, key string, expire time.Duration, fn func(ctx context.Context) (T, error)) (T, error) { + var t T + var write bool + v, err := rcClient.Fetch2(ctx, key, expire, func() (s string, err error) { + t, err = fn(ctx) + if err != nil { + return "", err + } + bs, err := json.Marshal(t) + if err != nil { + return "", errs.WrapMsg(err, "marshal failed") + } + write = true + + return string(bs), nil + }) + if err != nil { + return t, errs.Wrap(err) + } + if write { + return t, nil + } + if v == "" { + return t, errs.ErrRecordNotFound.WrapMsg("cache is not found") + } + err = json.Unmarshal([]byte(v), &t) + if err != nil { + errInfo := fmt.Sprintf("cache json.Unmarshal failed, key:%s, value:%s, expire:%s", key, v, expire) + return t, errs.WrapMsg(err, errInfo) + } + + return t, nil +} + +func batchGetCache[T any, K comparable]( + ctx context.Context, + rcClient *rockscache.Client, + expire time.Duration, + keys []K, + keyFn func(key K) string, + fns func(ctx context.Context, key K) (T, error), +) ([]T, error) { + if len(keys) == 0 { + return nil, nil + } + res := make([]T, 0, len(keys)) + for _, key := range keys { + val, err := getCache(ctx, rcClient, keyFn(key), expire, func(ctx context.Context) (T, error) { + return fns(ctx, key) + }) + if err != nil { + if errs.ErrRecordNotFound.Is(specialerror.ErrCode(errs.Unwrap(err))) { + continue + } + return nil, errs.Wrap(err) + } + res = append(res, val) + } + + return res, nil +} diff --git a/pkg/common/db/cache/black.go b/pkg/common/storage/cache/redis/black.go similarity index 59% rename from pkg/common/db/cache/black.go rename to pkg/common/storage/cache/redis/black.go index 615f2cbf1..fac6dbe6f 100644 --- a/pkg/common/db/cache/black.go +++ b/pkg/common/storage/cache/redis/black.go @@ -12,63 +12,49 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" - "time" - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" "github.com/openimsdk/tools/log" "github.com/redis/go-redis/v9" + "time" ) const ( - blackIDsKey = "BLACK_IDS:" blackExpireTime = time.Second * 60 * 60 * 12 ) -// args fn will exec when no data in msgCache. -type BlackCache interface { - // get blackIDs from msgCache - metaCache - NewCache() BlackCache - GetBlackIDs(ctx context.Context, userID string) (blackIDs []string, err error) - // del user's blackIDs msgCache, exec when a user's black list changed - DelBlackIDs(ctx context.Context, userID string) BlackCache -} - type BlackCacheRedis struct { - metaCache + cache.BatchDeleter expireTime time.Duration rcClient *rockscache.Client - blackDB relationtb.BlackModelInterface + blackDB database.Black } -func NewBlackCacheRedis(rdb redis.UniversalClient, localCache *config.LocalCache, blackDB relationtb.BlackModelInterface, options rockscache.Options) BlackCache { - rcClient := rockscache.NewClient(rdb, options) - mc := NewMetaCacheRedis(rcClient) +func NewBlackCacheRedis(rdb redis.UniversalClient, localCache *config.LocalCache, blackDB database.Black, options *rockscache.Options) cache.BlackCache { + batchHandler := NewBatchDeleterRedis(rdb, options, []string{localCache.Friend.Topic}) b := localCache.Friend log.ZDebug(context.Background(), "black local cache init", "Topic", b.Topic, "SlotNum", b.SlotNum, "SlotSize", b.SlotSize, "enable", b.Enable()) - mc.SetTopic(b.Topic) - mc.SetRawRedisClient(rdb) return &BlackCacheRedis{ - expireTime: blackExpireTime, - rcClient: rcClient, - metaCache: mc, - blackDB: blackDB, + BatchDeleter: batchHandler, + expireTime: blackExpireTime, + rcClient: rockscache.NewClient(rdb, *options), + blackDB: blackDB, } } -func (b *BlackCacheRedis) NewCache() BlackCache { +func (b *BlackCacheRedis) CloneBlackCache() cache.BlackCache { return &BlackCacheRedis{ - expireTime: b.expireTime, - rcClient: b.rcClient, - blackDB: b.blackDB, - metaCache: b.Copy(), + BatchDeleter: b.BatchDeleter.Clone(), + expireTime: b.expireTime, + rcClient: b.rcClient, + blackDB: b.blackDB, } } @@ -88,8 +74,8 @@ func (b *BlackCacheRedis) GetBlackIDs(ctx context.Context, userID string) (black ) } -func (b *BlackCacheRedis) DelBlackIDs(ctx context.Context, userID string) BlackCache { - cache := b.NewCache() +func (b *BlackCacheRedis) DelBlackIDs(_ context.Context, userID string) cache.BlackCache { + cache := b.CloneBlackCache() cache.AddKeys(b.getBlackIDsKey(userID)) return cache diff --git a/pkg/common/storage/cache/redis/conversation.go b/pkg/common/storage/cache/redis/conversation.go new file mode 100644 index 000000000..5fac79a7e --- /dev/null +++ b/pkg/common/storage/cache/redis/conversation.go @@ -0,0 +1,246 @@ +// 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 redis + +import ( + "context" + "github.com/dtm-labs/rockscache" + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/tools/log" + "github.com/openimsdk/tools/utils/datautil" + "github.com/openimsdk/tools/utils/encrypt" + "github.com/redis/go-redis/v9" + "math/big" + "strings" + "time" +) + +const ( + conversationExpireTime = time.Second * 60 * 60 * 12 +) + +func NewConversationRedis(rdb redis.UniversalClient, localCache *config.LocalCache, opts *rockscache.Options, db database.Conversation) cache.ConversationCache { + batchHandler := NewBatchDeleterRedis(rdb, opts, []string{localCache.Conversation.Topic}) + c := localCache.Conversation + log.ZDebug(context.Background(), "black local cache init", "Topic", c.Topic, "SlotNum", c.SlotNum, "SlotSize", c.SlotSize, "enable", c.Enable()) + return &ConversationRedisCache{ + BatchDeleter: batchHandler, + rcClient: rockscache.NewClient(rdb, *opts), + conversationDB: db, + expireTime: conversationExpireTime, + } +} + +type ConversationRedisCache struct { + cache.BatchDeleter + rcClient *rockscache.Client + conversationDB database.Conversation + expireTime time.Duration +} + +func (c *ConversationRedisCache) CloneConversationCache() cache.ConversationCache { + return &ConversationRedisCache{ + BatchDeleter: c.BatchDeleter.Clone(), + rcClient: c.rcClient, + conversationDB: c.conversationDB, + expireTime: c.expireTime, + } +} + +func (c *ConversationRedisCache) getConversationKey(ownerUserID, conversationID string) string { + return cachekey.GetConversationKey(ownerUserID, conversationID) +} + +func (c *ConversationRedisCache) getConversationIDsKey(ownerUserID string) string { + return cachekey.GetConversationIDsKey(ownerUserID) +} + +func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsKey(groupID string) string { + return cachekey.GetSuperGroupRecvNotNotifyUserIDsKey(groupID) +} + +func (c *ConversationRedisCache) getRecvMsgOptKey(ownerUserID, conversationID string) string { + return cachekey.GetRecvMsgOptKey(ownerUserID, conversationID) +} + +func (c *ConversationRedisCache) getSuperGroupRecvNotNotifyUserIDsHashKey(groupID string) string { + return cachekey.GetSuperGroupRecvNotNotifyUserIDsHashKey(groupID) +} + +func (c *ConversationRedisCache) getConversationHasReadSeqKey(ownerUserID, conversationID string) string { + return cachekey.GetConversationHasReadSeqKey(ownerUserID, conversationID) +} + +func (c *ConversationRedisCache) getConversationNotReceiveMessageUserIDsKey(conversationID string) string { + return cachekey.GetConversationNotReceiveMessageUserIDsKey(conversationID) +} + +func (c *ConversationRedisCache) getUserConversationIDsHashKey(ownerUserID string) string { + return cachekey.GetUserConversationIDsHashKey(ownerUserID) +} + +func (c *ConversationRedisCache) GetUserConversationIDs(ctx context.Context, ownerUserID string) ([]string, error) { + return getCache(ctx, c.rcClient, c.getConversationIDsKey(ownerUserID), c.expireTime, func(ctx context.Context) ([]string, error) { + return c.conversationDB.FindUserIDAllConversationID(ctx, ownerUserID) + }) +} + +func (c *ConversationRedisCache) DelConversationIDs(userIDs ...string) cache.ConversationCache { + keys := make([]string, 0, len(userIDs)) + for _, userID := range userIDs { + keys = append(keys, c.getConversationIDsKey(userID)) + } + cache := c.CloneConversationCache() + cache.AddKeys(keys...) + + return cache +} + +func (c *ConversationRedisCache) GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) { + return getCache( + ctx, + c.rcClient, + c.getUserConversationIDsHashKey(ownerUserID), + c.expireTime, + func(ctx context.Context) (uint64, error) { + conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID) + if err != nil { + return 0, err + } + datautil.Sort(conversationIDs, true) + bi := big.NewInt(0) + bi.SetString(encrypt.Md5(strings.Join(conversationIDs, ";"))[0:8], 16) + return bi.Uint64(), nil + }, + ) +} + +func (c *ConversationRedisCache) DelUserConversationIDsHash(ownerUserIDs ...string) cache.ConversationCache { + keys := make([]string, 0, len(ownerUserIDs)) + for _, ownerUserID := range ownerUserIDs { + keys = append(keys, c.getUserConversationIDsHashKey(ownerUserID)) + } + cache := c.CloneConversationCache() + cache.AddKeys(keys...) + + return cache +} + +func (c *ConversationRedisCache) GetConversation(ctx context.Context, ownerUserID, conversationID string) (*model.Conversation, error) { + return getCache(ctx, c.rcClient, c.getConversationKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (*model.Conversation, error) { + return c.conversationDB.Take(ctx, ownerUserID, conversationID) + }) +} + +func (c *ConversationRedisCache) DelConversations(ownerUserID string, conversationIDs ...string) cache.ConversationCache { + keys := make([]string, 0, len(conversationIDs)) + for _, conversationID := range conversationIDs { + keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) + } + cache := c.CloneConversationCache() + cache.AddKeys(keys...) + + return cache +} + +func (c *ConversationRedisCache) GetConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*model.Conversation, error) { + return batchGetCache(ctx, c.rcClient, c.expireTime, conversationIDs, func(conversationID string) string { + return c.getConversationKey(ownerUserID, conversationID) + }, func(ctx context.Context, conversationID string) (*model.Conversation, error) { + return c.conversationDB.Take(ctx, ownerUserID, conversationID) + }) +} + +func (c *ConversationRedisCache) GetUserAllConversations(ctx context.Context, ownerUserID string) ([]*model.Conversation, error) { + conversationIDs, err := c.GetUserConversationIDs(ctx, ownerUserID) + if err != nil { + return nil, err + } + return c.GetConversations(ctx, ownerUserID, conversationIDs) +} + +func (c *ConversationRedisCache) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) { + return getCache(ctx, c.rcClient, c.getRecvMsgOptKey(ownerUserID, conversationID), c.expireTime, func(ctx context.Context) (opt int, err error) { + return c.conversationDB.GetUserRecvMsgOpt(ctx, ownerUserID, conversationID) + }) +} + +func (c *ConversationRedisCache) DelUsersConversation(conversationID string, ownerUserIDs ...string) cache.ConversationCache { + keys := make([]string, 0, len(ownerUserIDs)) + for _, ownerUserID := range ownerUserIDs { + keys = append(keys, c.getConversationKey(ownerUserID, conversationID)) + } + cache := c.CloneConversationCache() + cache.AddKeys(keys...) + + return cache +} + +func (c *ConversationRedisCache) DelUserRecvMsgOpt(ownerUserID, conversationID string) cache.ConversationCache { + cache := c.CloneConversationCache() + cache.AddKeys(c.getRecvMsgOptKey(ownerUserID, conversationID)) + + return cache +} + +func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDs(groupID string) cache.ConversationCache { + cache := c.CloneConversationCache() + cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsKey(groupID)) + + return cache +} + +func (c *ConversationRedisCache) DelSuperGroupRecvMsgNotNotifyUserIDsHash(groupID string) cache.ConversationCache { + cache := c.CloneConversationCache() + cache.AddKeys(c.getSuperGroupRecvNotNotifyUserIDsHashKey(groupID)) + + return cache +} + +func (c *ConversationRedisCache) DelUserAllHasReadSeqs(ownerUserID string, conversationIDs ...string) cache.ConversationCache { + cache := c.CloneConversationCache() + for _, conversationID := range conversationIDs { + cache.AddKeys(c.getConversationHasReadSeqKey(ownerUserID, conversationID)) + } + + return cache +} + +func (c *ConversationRedisCache) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*model.Conversation, error) { + panic("implement me") +} + +func (c *ConversationRedisCache) DelConversationByConversationID(conversationIDs ...string) cache.ConversationCache { + panic("implement me") +} + +func (c *ConversationRedisCache) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) { + return getCache(ctx, c.rcClient, c.getConversationNotReceiveMessageUserIDsKey(conversationID), c.expireTime, func(ctx context.Context) ([]string, error) { + return c.conversationDB.GetConversationNotReceiveMessageUserIDs(ctx, conversationID) + }) +} + +func (c *ConversationRedisCache) DelConversationNotReceiveMessageUserIDs(conversationIDs ...string) cache.ConversationCache { + cache := c.CloneConversationCache() + for _, conversationID := range conversationIDs { + cache.AddKeys(c.getConversationNotReceiveMessageUserIDsKey(conversationID)) + } + + return cache +} diff --git a/pkg/common/storage/cache/redis/doc.go b/pkg/common/storage/cache/redis/doc.go new file mode 100644 index 000000000..4c2fcacd1 --- /dev/null +++ b/pkg/common/storage/cache/redis/doc.go @@ -0,0 +1,15 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package redis diff --git a/pkg/common/db/cache/friend.go b/pkg/common/storage/cache/redis/friend.go similarity index 67% rename from pkg/common/db/cache/friend.go rename to pkg/common/storage/cache/redis/friend.go index 73fe5ea69..f76e5ff6b 100644 --- a/pkg/common/db/cache/friend.go +++ b/pkg/common/storage/cache/redis/friend.go @@ -12,75 +12,54 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" - "time" - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" "github.com/redis/go-redis/v9" + "time" ) const ( friendExpireTime = time.Second * 60 * 60 * 12 - // FriendIDsKey = "FRIEND_IDS:" - // TwoWayFriendsIDsKey = "COMMON_FRIENDS_IDS:" - // friendKey = "FRIEND_INFO:". ) -// FriendCache is an interface for caching friend-related data. -type FriendCache interface { - metaCache - NewCache() FriendCache - GetFriendIDs(ctx context.Context, ownerUserID string) (friendIDs []string, err error) - // Called when friendID list changed - DelFriendIDs(ownerUserID ...string) FriendCache - // Get single friendInfo from the cache - GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) - // Delete friend when friend info changed - DelFriend(ownerUserID, friendUserID string) FriendCache - // Delete friends when friends' info changed - DelFriends(ownerUserID string, friendUserIDs []string) FriendCache -} - // FriendCacheRedis is an implementation of the FriendCache interface using Redis. type FriendCacheRedis struct { - metaCache - friendDB relationtb.FriendModelInterface + cache.BatchDeleter + friendDB database.Friend expireTime time.Duration rcClient *rockscache.Client } // NewFriendCacheRedis creates a new instance of FriendCacheRedis. -func NewFriendCacheRedis(rdb redis.UniversalClient, localCache *config.LocalCache, friendDB relationtb.FriendModelInterface, - options rockscache.Options) FriendCache { - rcClient := rockscache.NewClient(rdb, options) - mc := NewMetaCacheRedis(rcClient) +func NewFriendCacheRedis(rdb redis.UniversalClient, localCache *config.LocalCache, friendDB database.Friend, + options *rockscache.Options) cache.FriendCache { + batchHandler := NewBatchDeleterRedis(rdb, options, []string{localCache.Friend.Topic}) f := localCache.Friend log.ZDebug(context.Background(), "friend local cache init", "Topic", f.Topic, "SlotNum", f.SlotNum, "SlotSize", f.SlotSize, "enable", f.Enable()) - mc.SetTopic(f.Topic) - mc.SetRawRedisClient(rdb) return &FriendCacheRedis{ - metaCache: mc, - friendDB: friendDB, - expireTime: friendExpireTime, - rcClient: rcClient, + BatchDeleter: batchHandler, + friendDB: friendDB, + expireTime: friendExpireTime, + rcClient: rockscache.NewClient(rdb, *options), } } -// NewCache creates a new instance of FriendCacheRedis with the same configuration. -func (f *FriendCacheRedis) NewCache() FriendCache { +func (f *FriendCacheRedis) CloneFriendCache() cache.FriendCache { return &FriendCacheRedis{ - rcClient: f.rcClient, - metaCache: f.Copy(), - friendDB: f.friendDB, - expireTime: f.expireTime, + BatchDeleter: f.BatchDeleter.Clone(), + friendDB: f.friendDB, + expireTime: f.expireTime, + rcClient: f.rcClient, } } @@ -107,15 +86,15 @@ func (f *FriendCacheRedis) GetFriendIDs(ctx context.Context, ownerUserID string) } // DelFriendIDs deletes friend IDs from the cache. -func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) FriendCache { - newGroupCache := f.NewCache() +func (f *FriendCacheRedis) DelFriendIDs(ownerUserIDs ...string) cache.FriendCache { + newFriendCache := f.CloneFriendCache() keys := make([]string, 0, len(ownerUserIDs)) for _, userID := range ownerUserIDs { keys = append(keys, f.getFriendIDsKey(userID)) } - newGroupCache.AddKeys(keys...) + newFriendCache.AddKeys(keys...) - return newGroupCache + return newFriendCache } // GetTwoWayFriendIDs retrieves two-way friend IDs from the cache. @@ -138,32 +117,32 @@ func (f *FriendCacheRedis) GetTwoWayFriendIDs(ctx context.Context, ownerUserID s } // DelTwoWayFriendIDs deletes two-way friend IDs from the cache. -func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID string) FriendCache { - newFriendCache := f.NewCache() +func (f *FriendCacheRedis) DelTwoWayFriendIDs(ctx context.Context, ownerUserID string) cache.FriendCache { + newFriendCache := f.CloneFriendCache() newFriendCache.AddKeys(f.getTwoWayFriendsIDsKey(ownerUserID)) return newFriendCache } // GetFriend retrieves friend info from the cache or the database if not found. -func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *relationtb.FriendModel, err error) { +func (f *FriendCacheRedis) GetFriend(ctx context.Context, ownerUserID, friendUserID string) (friend *model.Friend, err error) { return getCache(ctx, f.rcClient, f.getFriendKey(ownerUserID, - friendUserID), f.expireTime, func(ctx context.Context) (*relationtb.FriendModel, error) { + friendUserID), f.expireTime, func(ctx context.Context) (*model.Friend, error) { return f.friendDB.Take(ctx, ownerUserID, friendUserID) }) } // DelFriend deletes friend info from the cache. -func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) FriendCache { - newFriendCache := f.NewCache() +func (f *FriendCacheRedis) DelFriend(ownerUserID, friendUserID string) cache.FriendCache { + newFriendCache := f.CloneFriendCache() newFriendCache.AddKeys(f.getFriendKey(ownerUserID, friendUserID)) return newFriendCache } // DelFriends deletes multiple friend infos from the cache. -func (f *FriendCacheRedis) DelFriends(ownerUserID string, friendUserIDs []string) FriendCache { - newFriendCache := f.NewCache() +func (f *FriendCacheRedis) DelFriends(ownerUserID string, friendUserIDs []string) cache.FriendCache { + newFriendCache := f.CloneFriendCache() for _, friendUserID := range friendUserIDs { key := f.getFriendKey(ownerUserID, friendUserID) diff --git a/pkg/common/db/cache/group.go b/pkg/common/storage/cache/redis/group.go similarity index 61% rename from pkg/common/db/cache/group.go rename to pkg/common/storage/cache/redis/group.go index 66c2d65c4..2de03906f 100644 --- a/pkg/common/db/cache/group.go +++ b/pkg/common/storage/cache/redis/group.go @@ -12,110 +12,74 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" "fmt" - "time" - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/common" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" "github.com/redis/go-redis/v9" + "time" ) const ( groupExpireTime = time.Second * 60 * 60 * 12 ) -type GroupHash interface { - GetGroupHash(ctx context.Context, groupID string) (uint64, error) -} - -type GroupCache interface { - metaCache - NewCache() GroupCache - GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) - GetGroupInfo(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) - DelGroupsInfo(groupIDs ...string) GroupCache - - GetGroupMembersHash(ctx context.Context, groupID string) (hashCode uint64, err error) - GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) - DelGroupMembersHash(groupID string) GroupCache - - GetGroupMemberIDs(ctx context.Context, groupID string) (groupMemberIDs []string, err error) - GetGroupsMemberIDs(ctx context.Context, groupIDs []string) (groupMemberIDs map[string][]string, err error) - - DelGroupMemberIDs(groupID string) GroupCache - - GetJoinedGroupIDs(ctx context.Context, userID string) (joinedGroupIDs []string, err error) - DelJoinedGroupID(userID ...string) GroupCache - - GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationtb.GroupMemberModel, err error) - GetGroupMembersInfo(ctx context.Context, groupID string, userID []string) (groupMembers []*relationtb.GroupMemberModel, err error) - GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) - GetGroupMembersPage(ctx context.Context, groupID string, userID []string, showNumber, pageNumber int32) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) - FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) - - GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) - GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) - GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) - DelGroupRoleLevel(groupID string, roleLevel []int32) GroupCache - DelGroupAllRoleLevel(groupID string) GroupCache - DelGroupMembersInfo(groupID string, userID ...string) GroupCache - GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) - GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) - GetGroupMemberNum(ctx context.Context, groupID string) (memberNum int64, err error) - DelGroupsMemberNum(groupID ...string) GroupCache -} +var errIndex = errs.New("err index") type GroupCacheRedis struct { - metaCache - groupDB relationtb.GroupModelInterface - groupMemberDB relationtb.GroupMemberModelInterface - groupRequestDB relationtb.GroupRequestModelInterface + cache.BatchDeleter + groupDB database.Group + groupMemberDB database.GroupMember + groupRequestDB database.GroupRequest expireTime time.Duration rcClient *rockscache.Client - groupHash GroupHash + groupHash cache.GroupHash } func NewGroupCacheRedis( rdb redis.UniversalClient, localCache *config.LocalCache, - groupDB relationtb.GroupModelInterface, - groupMemberDB relationtb.GroupMemberModelInterface, - groupRequestDB relationtb.GroupRequestModelInterface, - hashCode GroupHash, - opts rockscache.Options, -) GroupCache { - rcClient := rockscache.NewClient(rdb, opts) - mc := NewMetaCacheRedis(rcClient) + groupDB database.Group, + groupMemberDB database.GroupMember, + groupRequestDB database.GroupRequest, + hashCode cache.GroupHash, + opts *rockscache.Options, +) cache.GroupCache { + batchHandler := NewBatchDeleterRedis(rdb, opts, []string{localCache.Group.Topic}) g := localCache.Group - mc.SetTopic(g.Topic) log.ZDebug(context.Background(), "group local cache init", "Topic", g.Topic, "SlotNum", g.SlotNum, "SlotSize", g.SlotSize, "enable", g.Enable()) - mc.SetRawRedisClient(rdb) + return &GroupCacheRedis{ - rcClient: rcClient, expireTime: groupExpireTime, - groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, - groupHash: hashCode, - metaCache: mc, + BatchDeleter: batchHandler, + rcClient: rockscache.NewClient(rdb, *opts), + expireTime: groupExpireTime, + groupDB: groupDB, + groupMemberDB: groupMemberDB, + groupRequestDB: groupRequestDB, + groupHash: hashCode, } } -func (g *GroupCacheRedis) NewCache() GroupCache { +func (g *GroupCacheRedis) CloneGroupCache() cache.GroupCache { return &GroupCacheRedis{ + BatchDeleter: g.BatchDeleter.Clone(), rcClient: g.rcClient, expireTime: g.expireTime, groupDB: g.groupDB, groupMemberDB: g.groupMemberDB, groupRequestDB: g.groupRequestDB, - metaCache: g.Copy(), } } @@ -147,7 +111,7 @@ func (g *GroupCacheRedis) getGroupRoleLevelMemberIDsKey(groupID string, roleLeve return cachekey.GetGroupRoleLevelMemberIDsKey(groupID, roleLevel) } -func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []string) (int, error) { +func (g *GroupCacheRedis) GetGroupIndex(group *model.Group, keys []string) (int, error) { key := g.getGroupInfoKey(group.GroupID) for i, _key := range keys { if _key == key { @@ -158,7 +122,7 @@ func (g *GroupCacheRedis) GetGroupIndex(group *relationtb.GroupModel, keys []str return 0, errIndex } -func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMemberModel, keys []string) (int, error) { +func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *model.GroupMember, keys []string) (int, error) { key := g.getGroupMemberInfoKey(groupMember.GroupID, groupMember.UserID) for i, _key := range keys { if _key == key { @@ -169,22 +133,22 @@ func (g *GroupCacheRedis) GetGroupMemberIndex(groupMember *relationtb.GroupMembe return 0, errIndex } -func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) { - return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { +func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*model.Group, err error) { + return batchGetCache(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { return g.getGroupInfoKey(groupID) - }, func(ctx context.Context, groupID string) (*relationtb.GroupModel, error) { + }, func(ctx context.Context, groupID string) (*model.Group, error) { return g.groupDB.Take(ctx, groupID) }) } -func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) { - return getCache(ctx, g.rcClient, g.getGroupInfoKey(groupID), g.expireTime, func(ctx context.Context) (*relationtb.GroupModel, error) { +func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID string) (group *model.Group, err error) { + return getCache(ctx, g.rcClient, g.getGroupInfoKey(groupID), g.expireTime, func(ctx context.Context) (*model.Group, error) { return g.groupDB.Take(ctx, groupID) }) } -func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache { - newGroupCache := g.NewCache() +func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) cache.GroupCache { + newGroupCache := g.CloneGroupCache() keys := make([]string, 0, len(groupIDs)) for _, groupID := range groupIDs { keys = append(keys, g.getGroupInfoKey(groupID)) @@ -194,8 +158,8 @@ func (g *GroupCacheRedis) DelGroupsInfo(groupIDs ...string) GroupCache { return newGroupCache } -func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) GroupCache { - newGroupCache := g.NewCache() +func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) cache.GroupCache { + newGroupCache := g.CloneGroupCache() keys := make([]string, 0, len(groupIDs)) for _, groupID := range groupIDs { keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, constant.GroupOwner)) @@ -205,8 +169,8 @@ func (g *GroupCacheRedis) DelGroupsOwner(groupIDs ...string) GroupCache { return newGroupCache } -func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) GroupCache { - newGroupCache := g.NewCache() +func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) cache.GroupCache { + newGroupCache := g.CloneGroupCache() keys := make([]string, 0, len(roleLevels)) for _, roleLevel := range roleLevels { keys = append(keys, g.getGroupRoleLevelMemberIDsKey(groupID, roleLevel)) @@ -215,7 +179,7 @@ func (g *GroupCacheRedis) DelGroupRoleLevel(groupID string, roleLevels []int32) return newGroupCache } -func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) GroupCache { +func (g *GroupCacheRedis) DelGroupAllRoleLevel(groupID string) cache.GroupCache { return g.DelGroupRoleLevel(groupID, []int32{constant.GroupOwner, constant.GroupAdmin, constant.GroupOrdinaryUsers}) } @@ -228,11 +192,11 @@ func (g *GroupCacheRedis) GetGroupMembersHash(ctx context.Context, groupID strin }) } -func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) { +func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs []string) (map[string]*common.GroupSimpleUserID, error) { if g.groupHash == nil { return nil, errs.ErrInternalServer.WrapMsg("group hash is nil") } - res := make(map[string]*relationtb.GroupSimpleUserID) + res := make(map[string]*common.GroupSimpleUserID) for _, groupID := range groupIDs { hash, err := g.GetGroupMembersHash(ctx, groupID) if err != nil { @@ -243,14 +207,14 @@ func (g *GroupCacheRedis) GetGroupMemberHashMap(ctx context.Context, groupIDs [] if err != nil { return nil, err } - res[groupID] = &relationtb.GroupSimpleUserID{Hash: hash, MemberNum: uint32(num)} + res[groupID] = &common.GroupSimpleUserID{Hash: hash, MemberNum: uint32(num)} } return res, nil } -func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) GroupCache { - cache := g.NewCache() +func (g *GroupCacheRedis) DelGroupMembersHash(groupID string) cache.GroupCache { + cache := g.CloneGroupCache() cache.AddKeys(g.getGroupMembersHashKey(groupID)) return cache @@ -275,8 +239,8 @@ func (g *GroupCacheRedis) GetGroupsMemberIDs(ctx context.Context, groupIDs []str return m, nil } -func (g *GroupCacheRedis) DelGroupMemberIDs(groupID string) GroupCache { - cache := g.NewCache() +func (g *GroupCacheRedis) DelGroupMemberIDs(groupID string) cache.GroupCache { + cache := g.CloneGroupCache() cache.AddKeys(g.getGroupMemberIDsKey(groupID)) return cache @@ -288,27 +252,27 @@ func (g *GroupCacheRedis) GetJoinedGroupIDs(ctx context.Context, userID string) }) } -func (g *GroupCacheRedis) DelJoinedGroupID(userIDs ...string) GroupCache { +func (g *GroupCacheRedis) DelJoinedGroupID(userIDs ...string) cache.GroupCache { keys := make([]string, 0, len(userIDs)) for _, userID := range userIDs { keys = append(keys, g.getJoinedGroupsKey(userID)) } - cache := g.NewCache() + cache := g.CloneGroupCache() cache.AddKeys(keys...) return cache } -func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *relationtb.GroupMemberModel, err error) { - return getCache(ctx, g.rcClient, g.getGroupMemberInfoKey(groupID, userID), g.expireTime, func(ctx context.Context) (*relationtb.GroupMemberModel, error) { +func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userID string) (groupMember *model.GroupMember, err error) { + return getCache(ctx, g.rcClient, g.getGroupMemberInfoKey(groupID, userID), g.expireTime, func(ctx context.Context) (*model.GroupMember, error) { return g.groupMemberDB.Take(ctx, groupID, userID) }) } -func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) { - return batchGetCache2(ctx, g.rcClient, g.expireTime, userIDs, func(userID string) string { +func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupMember, error) { + return batchGetCache(ctx, g.rcClient, g.expireTime, userIDs, func(userID string) string { return g.getGroupMemberInfoKey(groupID, userID) - }, func(ctx context.Context, userID string) (*relationtb.GroupMemberModel, error) { + }, func(ctx context.Context, userID string) (*model.GroupMember, error) { return g.groupMemberDB.Take(ctx, groupID, userID) }) } @@ -318,7 +282,7 @@ func (g *GroupCacheRedis) GetGroupMembersPage( groupID string, userIDs []string, showNumber, pageNumber int32, -) (total uint32, groupMembers []*relationtb.GroupMemberModel, err error) { +) (total uint32, groupMembers []*model.GroupMember, err error) { groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID) if err != nil { return 0, nil, err @@ -333,7 +297,7 @@ func (g *GroupCacheRedis) GetGroupMembersPage( return uint32(len(userIDs)), groupMembers, err } -func (g *GroupCacheRedis) GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) { +func (g *GroupCacheRedis) GetAllGroupMembersInfo(ctx context.Context, groupID string) (groupMembers []*model.GroupMember, err error) { groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID) if err != nil { return nil, err @@ -342,7 +306,7 @@ func (g *GroupCacheRedis) GetAllGroupMembersInfo(ctx context.Context, groupID st return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs) } -func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) { +func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID string) ([]*model.GroupMember, error) { groupMemberIDs, err := g.GetGroupMemberIDs(ctx, groupID) if err != nil { return nil, err @@ -350,12 +314,12 @@ func (g *GroupCacheRedis) GetAllGroupMemberInfo(ctx context.Context, groupID str return g.GetGroupMembersInfo(ctx, groupID, groupMemberIDs) } -func (g *GroupCacheRedis) DelGroupMembersInfo(groupID string, userIDs ...string) GroupCache { +func (g *GroupCacheRedis) DelGroupMembersInfo(groupID string, userIDs ...string) cache.GroupCache { keys := make([]string, 0, len(userIDs)) for _, userID := range userIDs { keys = append(keys, g.getGroupMemberInfoKey(groupID, userID)) } - cache := g.NewCache() + cache := g.CloneGroupCache() cache.AddKeys(keys...) return cache @@ -367,18 +331,18 @@ func (g *GroupCacheRedis) GetGroupMemberNum(ctx context.Context, groupID string) }) } -func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) GroupCache { +func (g *GroupCacheRedis) DelGroupsMemberNum(groupID ...string) cache.GroupCache { keys := make([]string, 0, len(groupID)) for _, groupID := range groupID { keys = append(keys, g.getGroupMemberNumKey(groupID)) } - cache := g.NewCache() + cache := g.CloneGroupCache() cache.AddKeys(keys...) return cache } -func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { +func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*model.GroupMember, error) { members, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner) if err != nil { return nil, err @@ -389,8 +353,8 @@ func (g *GroupCacheRedis) GetGroupOwner(ctx context.Context, groupID string) (*r return members[0], nil } -func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) { - members := make([]*relationtb.GroupMemberModel, 0, len(groupIDs)) +func (g *GroupCacheRedis) GetGroupsOwner(ctx context.Context, groupIDs []string) ([]*model.GroupMember, error) { + members := make([]*model.GroupMember, 0, len(groupIDs)) for _, groupID := range groupIDs { items, err := g.GetGroupRoleLevelMemberInfo(ctx, groupID, constant.GroupOwner) if err != nil { @@ -409,7 +373,7 @@ func (g *GroupCacheRedis) GetGroupRoleLevelMemberIDs(ctx context.Context, groupI }) } -func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*relationtb.GroupMemberModel, error) { +func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, groupID string, roleLevel int32) ([]*model.GroupMember, error) { userIDs, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) if err != nil { return nil, err @@ -417,7 +381,7 @@ func (g *GroupCacheRedis) GetGroupRoleLevelMemberInfo(ctx context.Context, group return g.GetGroupMembersInfo(ctx, groupID, userIDs) } -func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { +func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, groupID string, roleLevels []int32) ([]*model.GroupMember, error) { var userIDs []string for _, roleLevel := range roleLevels { ids, err := g.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) @@ -429,16 +393,16 @@ func (g *GroupCacheRedis) GetGroupRolesLevelMemberInfo(ctx context.Context, grou return g.GetGroupMembersInfo(ctx, groupID, userIDs) } -func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (_ []*relationtb.GroupMemberModel, err error) { +func (g *GroupCacheRedis) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (_ []*model.GroupMember, err error) { if len(groupIDs) == 0 { groupIDs, err = g.GetJoinedGroupIDs(ctx, userID) if err != nil { return nil, err } } - return batchGetCache2(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { + return batchGetCache(ctx, g.rcClient, g.expireTime, groupIDs, func(groupID string) string { return g.getGroupMemberInfoKey(groupID, userID) - }, func(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { + }, func(ctx context.Context, groupID string) (*model.GroupMember, error) { return g.groupMemberDB.Take(ctx, groupID, userID) }) } diff --git a/pkg/common/storage/cache/redis/meta_cache.go b/pkg/common/storage/cache/redis/meta_cache.go new file mode 100644 index 000000000..4c2fcacd1 --- /dev/null +++ b/pkg/common/storage/cache/redis/meta_cache.go @@ -0,0 +1,15 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package redis diff --git a/pkg/common/db/cache/msg.go b/pkg/common/storage/cache/redis/msg.go similarity index 68% rename from pkg/common/db/cache/msg.go rename to pkg/common/storage/cache/redis/msg.go index e8a86b71b..df69bc645 100644 --- a/pkg/common/db/cache/msg.go +++ b/pkg/common/storage/cache/redis/msg.go @@ -12,15 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" "errors" - "strconv" - "time" - "github.com/gogo/protobuf/jsonpb" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/sdkws" @@ -29,78 +28,48 @@ import ( "github.com/openimsdk/tools/utils/stringutil" "github.com/redis/go-redis/v9" "golang.org/x/sync/errgroup" + "time" ) const msgCacheTimeout = 86400 * time.Second -const ( - maxSeq = "MAX_SEQ:" - minSeq = "MIN_SEQ:" - conversationUserMinSeq = "CON_USER_MIN_SEQ:" - hasReadSeq = "HAS_READ_SEQ:" - - getuiToken = "GETUI_TOKEN" - getuiTaskID = "GETUI_TASK_ID" - FCM_TOKEN = "FCM_TOKEN:" - - messageCache = "MESSAGE_CACHE:" - messageDelUserList = "MESSAGE_DEL_USER_LIST:" - userDelMessagesList = "USER_DEL_MESSAGES_LIST:" - sendMsgFailedFlag = "SEND_MSG_FAILED_FLAG:" - userBadgeUnreadCountSum = "USER_BADGE_UNREAD_COUNT_SUM:" - exTypeKeyLocker = "EX_LOCK:" -) - var concurrentLimit = 3 -//type MsgModel interface { -// SeqCache -// ThirdCache -// MsgCache -//} - -type MsgCache interface { - GetMessagesBySeq(ctx context.Context, conversationID string, seqs []int64) (seqMsg []*sdkws.MsgData, failedSeqList []int64, err error) - SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error) - UserDeleteMsgs(ctx context.Context, conversationID string, seqs []int64, userID string) error - DelUserDeleteMsgsList(ctx context.Context, conversationID string, seqs []int64) - DeleteMessages(ctx context.Context, conversationID string, seqs []int64) error - GetUserDelList(ctx context.Context, userID, conversationID string) (seqs []int64, err error) - CleanUpOneConversationAllMsg(ctx context.Context, conversationID string) error - DelMsgFromCache(ctx context.Context, userID string, seqList []int64) error - SetSendMsgStatus(ctx context.Context, id string, status int32) error - GetSendMsgStatus(ctx context.Context, id string) (int32, error) - JudgeMessageReactionExist(ctx context.Context, clientMsgID string, sessionType int32) (bool, error) - GetOneMessageAllReactionList(ctx context.Context, clientMsgID string, sessionType int32) (map[string]string, error) - DeleteOneMessageKey(ctx context.Context, clientMsgID string, sessionType int32, subKey string) error - SetMessageReactionExpire(ctx context.Context, clientMsgID string, sessionType int32, expiration time.Duration) (bool, error) - GetMessageTypeKeyValue(ctx context.Context, clientMsgID string, sessionType int32, typeKey string) (string, error) - SetMessageTypeKeyValue(ctx context.Context, clientMsgID string, sessionType int32, typeKey, value string) error - LockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error - UnLockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error -} - -//func NewMsgCacheModel(client redis.UniversalClient, msgCacheTimeout int, redisConf *config.Redis) MsgModel { -// return &msgCache{rdb: client, msgCacheTimeout: msgCacheTimeout, redisConf: redisConf} -//} - -func NewMsgCache(client redis.UniversalClient, redisEnablePipeline bool) MsgCache { +func NewMsgCache(client redis.UniversalClient, redisEnablePipeline bool) cache.MsgCache { return &msgCache{rdb: client, msgCacheTimeout: msgCacheTimeout, redisEnablePipeline: redisEnablePipeline} } type msgCache struct { - metaCache rdb redis.UniversalClient msgCacheTimeout time.Duration redisEnablePipeline bool } -func (c *msgCache) allMessageCacheKey(conversationID string) string { - return messageCache + conversationID + "_*" +func (c *msgCache) getAllMessageCacheKey(conversationID string) string { + return cachekey.GetAllMessageCacheKey(conversationID) } func (c *msgCache) getMessageCacheKey(conversationID string, seq int64) string { - return messageCache + conversationID + "_" + strconv.Itoa(int(seq)) + return cachekey.GetMessageCacheKey(conversationID, seq) +} +func (c *msgCache) getMessageDelUserListKey(conversationID string, seq int64) string { + return cachekey.GetMessageDelUserListKey(conversationID, seq) +} + +func (c *msgCache) getUserDelList(conversationID, userID string) string { + return cachekey.GetUserDelListKey(conversationID, userID) +} + +func (c *msgCache) getSendMsgKey(id string) string { + return cachekey.GetSendMsgKey(id) +} + +func (c *msgCache) getLockMessageTypeKey(clientMsgID string, TypeKey string) string { + return cachekey.GetLockMessageTypeKey(clientMsgID, TypeKey) +} + +func (c *msgCache) getMessageReactionExPrefix(clientMsgID string, sessionType int32) string { + return cachekey.GetMessageReactionExKey(clientMsgID, sessionType) } func (c *msgCache) SetMessageToCache(ctx context.Context, conversationID string, msgs []*sdkws.MsgData) (int, error) { @@ -164,14 +133,6 @@ func (c *msgCache) ParallelSetMessageToCache(ctx context.Context, conversationID return len(msgs), nil } -func (c *msgCache) getMessageDelUserListKey(conversationID string, seq int64) string { - return messageDelUserList + conversationID + ":" + strconv.Itoa(int(seq)) -} - -func (c *msgCache) getUserDelList(conversationID, userID string) string { - return userDelMessagesList + conversationID + ":" + userID -} - func (c *msgCache) UserDeleteMsgs(ctx context.Context, conversationID string, seqs []int64, userID string) error { for _, seq := range seqs { delUserListKey := c.getMessageDelUserListKey(conversationID, seq) @@ -193,27 +154,6 @@ func (c *msgCache) UserDeleteMsgs(ctx context.Context, conversationID string, se } return nil - // pipe := c.rdb.Pipeline() - // for _, seq := range seqs { - // delUserListKey := c.getMessageDelUserListKey(conversationID, seq) - // userDelListKey := c.getUserDelList(conversationID, userID) - // err := pipe.SAdd(ctx, delUserListKey, userID).Err() - // if err != nil { - // return errs.Wrap(err) - // } - // err = pipe.SAdd(ctx, userDelListKey, seq).Err() - // if err != nil { - // return errs.Wrap(err) - // } - // if err := pipe.Expire(ctx, delUserListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil { - // return errs.Wrap(err) - // } - // if err := pipe.Expire(ctx, userDelListKey, time.Duration(config.Config.MsgCacheTimeout)*time.Second).Err(); err != nil { - // return errs.Wrap(err) - // } - //} - // _, err := pipe.Exec(ctx) - // return errs.Wrap(err) } func (c *msgCache) GetUserDelList(ctx context.Context, userID, conversationID string) (seqs []int64, err error) { @@ -253,42 +193,6 @@ func (c *msgCache) DelUserDeleteMsgsList(ctx context.Context, conversationID str } } } - // for _, seq := range seqs { - // delUsers, err := c.rdb.SMembers(ctx, c.getMessageDelUserListKey(conversationID, seq)).Result() - // if err != nil { - // log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq) - // continue - // } - // if len(delUsers) > 0 { - // pipe := c.rdb.Pipeline() - // var failedFlag bool - // for _, userID := range delUsers { - // err = pipe.SRem(ctx, c.getUserDelList(conversationID, userID), seq).Err() - // if err != nil { - // failedFlag = true - // log.ZWarn( - // ctx, - // "DelUserDeleteMsgsList failed", - // err, - // "conversationID", - // conversationID, - // "seq", - // seq, - // "userID", - // userID, - // ) - // } - // } - // if !failedFlag { - // if err := pipe.Del(ctx, c.getMessageDelUserListKey(conversationID, seq)).Err(); err != nil { - // log.ZWarn(ctx, "DelUserDeleteMsgsList failed", err, "conversationID", conversationID, "seq", seq) - // } - // } - // if _, err := pipe.Exec(ctx); err != nil { - // log.ZError(ctx, "pipe exec failed", err, "conversationID", conversationID, "seq", seq) - // } - // } - //} } func (c *msgCache) DeleteMessages(ctx context.Context, conversationID string, seqs []int64) error { @@ -338,7 +242,7 @@ func (c *msgCache) PipeDeleteMessages(ctx context.Context, conversationID string } func (c *msgCache) CleanUpOneConversationAllMsg(ctx context.Context, conversationID string) error { - vals, err := c.rdb.Keys(ctx, c.allMessageCacheKey(conversationID)).Result() + vals, err := c.rdb.Keys(ctx, c.getAllMessageCacheKey(conversationID)).Result() if errors.Is(err, redis.Nil) { return nil } @@ -383,42 +287,24 @@ func (c *msgCache) DelMsgFromCache(ctx context.Context, userID string, seqs []in } func (c *msgCache) SetSendMsgStatus(ctx context.Context, id string, status int32) error { - return errs.Wrap(c.rdb.Set(ctx, sendMsgFailedFlag+id, status, time.Hour*24).Err()) + return errs.Wrap(c.rdb.Set(ctx, c.getSendMsgKey(id), status, time.Hour*24).Err()) } func (c *msgCache) GetSendMsgStatus(ctx context.Context, id string) (int32, error) { - result, err := c.rdb.Get(ctx, sendMsgFailedFlag+id).Int() - + result, err := c.rdb.Get(ctx, c.getSendMsgKey(id)).Int() return int32(result), errs.Wrap(err) } func (c *msgCache) LockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error { - key := exTypeKeyLocker + clientMsgID + "_" + TypeKey - + key := c.getLockMessageTypeKey(clientMsgID, TypeKey) return errs.Wrap(c.rdb.SetNX(ctx, key, 1, time.Minute).Err()) } func (c *msgCache) UnLockMessageTypeKey(ctx context.Context, clientMsgID string, TypeKey string) error { - key := exTypeKeyLocker + clientMsgID + "_" + TypeKey - + key := c.getLockMessageTypeKey(clientMsgID, TypeKey) return errs.Wrap(c.rdb.Del(ctx, key).Err()) } -func (c *msgCache) getMessageReactionExPrefix(clientMsgID string, sessionType int32) string { - switch sessionType { - case constant.SingleChatType: - return "EX_SINGLE_" + clientMsgID - case constant.WriteGroupChatType: - return "EX_GROUP_" + clientMsgID - case constant.ReadGroupChatType: - return "EX_SUPER_GROUP_" + clientMsgID - case constant.NotificationChatType: - return "EX_NOTIFICATION" + clientMsgID - } - - return "" -} - func (c *msgCache) JudgeMessageReactionExist(ctx context.Context, clientMsgID string, sessionType int32) (bool, error) { n, err := c.rdb.Exists(ctx, c.getMessageReactionExPrefix(clientMsgID, sessionType)).Result() if err != nil { diff --git a/pkg/common/db/cache/msg_test.go b/pkg/common/storage/cache/redis/msg_test.go similarity index 99% rename from pkg/common/db/cache/msg_test.go rename to pkg/common/storage/cache/redis/msg_test.go index 481b4012c..d47fa18e1 100644 --- a/pkg/common/db/cache/msg_test.go +++ b/pkg/common/storage/cache/redis/msg_test.go @@ -12,17 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" "fmt" - "math/rand" - "testing" - "github.com/openimsdk/protocol/sdkws" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" + "math/rand" + "testing" ) func TestParallelSetMessageToCache(t *testing.T) { diff --git a/pkg/common/db/cache/s3.go b/pkg/common/storage/cache/redis/s3.go similarity index 52% rename from pkg/common/db/cache/s3.go rename to pkg/common/storage/cache/redis/s3.go index 1610283ca..954557aca 100644 --- a/pkg/common/db/cache/s3.go +++ b/pkg/common/storage/cache/redis/s3.go @@ -12,55 +12,55 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" - "github.com/openimsdk/tools/s3/cont" - "github.com/openimsdk/tools/s3/minio" - "strconv" - "time" - "github.com/dtm-labs/rockscache" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/s3" + "github.com/openimsdk/tools/s3/cont" + "github.com/openimsdk/tools/s3/minio" "github.com/redis/go-redis/v9" + "time" ) -type ObjectCache interface { - metaCache - GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error) - DelObjectName(engine string, names ...string) ObjectCache -} - -func NewObjectCacheRedis(rdb redis.UniversalClient, objDB relationtb.ObjectInfoModelInterface) ObjectCache { - rcClient := rockscache.NewClient(rdb, rockscache.NewDefaultOptions()) +func NewObjectCacheRedis(rdb redis.UniversalClient, objDB database.ObjectInfo) cache.ObjectCache { + opts := rockscache.NewDefaultOptions() + batchHandler := NewBatchDeleterRedis(rdb, &opts, nil) return &objectCacheRedis{ - rcClient: rcClient, - expireTime: time.Hour * 12, - objDB: objDB, - metaCache: NewMetaCacheRedis(rcClient), + BatchDeleter: batchHandler, + rcClient: rockscache.NewClient(rdb, opts), + expireTime: time.Hour * 12, + objDB: objDB, } } type objectCacheRedis struct { - metaCache - objDB relationtb.ObjectInfoModelInterface + cache.BatchDeleter + objDB database.ObjectInfo rcClient *rockscache.Client expireTime time.Duration } -func (g *objectCacheRedis) NewCache() ObjectCache { +func (g *objectCacheRedis) getObjectKey(engine string, name string) string { + return cachekey.GetObjectKey(engine, name) +} + +func (g *objectCacheRedis) CloneObjectCache() cache.ObjectCache { return &objectCacheRedis{ - rcClient: g.rcClient, - expireTime: g.expireTime, - objDB: g.objDB, - metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...), + BatchDeleter: g.BatchDeleter.Clone(), + rcClient: g.rcClient, + expireTime: g.expireTime, + objDB: g.objDB, } } -func (g *objectCacheRedis) DelObjectName(engine string, names ...string) ObjectCache { - objectCache := g.NewCache() +func (g *objectCacheRedis) DelObjectName(engine string, names ...string) cache.ObjectCache { + objectCache := g.CloneObjectCache() keys := make([]string, 0, len(names)) for _, name := range names { keys = append(keys, g.getObjectKey(name, engine)) @@ -69,60 +69,40 @@ func (g *objectCacheRedis) DelObjectName(engine string, names ...string) ObjectC return objectCache } -func (g *objectCacheRedis) getObjectKey(engine string, name string) string { - return "OBJECT:" + engine + ":" + name -} - -func (g *objectCacheRedis) GetName(ctx context.Context, engine string, name string) (*relationtb.ObjectModel, error) { - return getCache(ctx, g.rcClient, g.getObjectKey(name, engine), g.expireTime, func(ctx context.Context) (*relationtb.ObjectModel, error) { +func (g *objectCacheRedis) GetName(ctx context.Context, engine string, name string) (*model.Object, error) { + return getCache(ctx, g.rcClient, g.getObjectKey(name, engine), g.expireTime, func(ctx context.Context) (*model.Object, error) { return g.objDB.Take(ctx, engine, name) }) } -type S3Cache interface { - metaCache - GetKey(ctx context.Context, engine string, key string) (*s3.ObjectInfo, error) - DelS3Key(engine string, keys ...string) S3Cache -} - func NewS3Cache(rdb redis.UniversalClient, s3 s3.Interface) cont.S3Cache { - rcClient := rockscache.NewClient(rdb, rockscache.NewDefaultOptions()) + opts := rockscache.NewDefaultOptions() + batchHandler := NewBatchDeleterRedis(rdb, &opts, nil) return &s3CacheRedis{ - rcClient: rcClient, - expireTime: time.Hour * 12, - s3: s3, - metaCache: NewMetaCacheRedis(rcClient), + BatchDeleter: batchHandler, + rcClient: rockscache.NewClient(rdb, opts), + expireTime: time.Hour * 12, + s3: s3, } } type s3CacheRedis struct { - metaCache + cache.BatchDeleter s3 s3.Interface rcClient *rockscache.Client expireTime time.Duration } -func (g *s3CacheRedis) newCache() *s3CacheRedis { - return &s3CacheRedis{ - rcClient: g.rcClient, - expireTime: g.expireTime, - s3: g.s3, - metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...), - } +func (g *s3CacheRedis) getS3Key(engine string, name string) string { + return cachekey.GetS3Key(engine, name) } func (g *s3CacheRedis) DelS3Key(ctx context.Context, engine string, keys ...string) error { - s3cache := g.newCache() ks := make([]string, 0, len(keys)) for _, key := range keys { ks = append(ks, g.getS3Key(engine, key)) } - s3cache.AddKeys(ks...) - return s3cache.ExecDel(ctx) -} - -func (g *s3CacheRedis) getS3Key(engine string, name string) string { - return "S3:" + engine + ":" + name + return g.BatchDeleter.ExecDelWithKeys(ctx, ks) } func (g *s3CacheRedis) GetKey(ctx context.Context, engine string, name string) (*s3.ObjectInfo, error) { @@ -131,59 +111,41 @@ func (g *s3CacheRedis) GetKey(ctx context.Context, engine string, name string) ( }) } -type MinioCache interface { - metaCache - GetImageObjectKeyInfo(ctx context.Context, key string, fn func(ctx context.Context) (*MinioImageInfo, error)) (*MinioImageInfo, error) - GetThumbnailKey(ctx context.Context, key string, format string, width int, height int, minioCache func(ctx context.Context) (string, error)) (string, error) - DelObjectImageInfoKey(keys ...string) MinioCache - DelImageThumbnailKey(key string, format string, width int, height int) MinioCache -} - func NewMinioCache(rdb redis.UniversalClient) minio.Cache { - rcClient := rockscache.NewClient(rdb, rockscache.NewDefaultOptions()) + opts := rockscache.NewDefaultOptions() + batchHandler := NewBatchDeleterRedis(rdb, &opts, nil) return &minioCacheRedis{ - rcClient: rcClient, - expireTime: time.Hour * 24 * 7, - metaCache: NewMetaCacheRedis(rcClient), + BatchDeleter: batchHandler, + rcClient: rockscache.NewClient(rdb, opts), + expireTime: time.Hour * 24 * 7, } } type minioCacheRedis struct { - metaCache + cache.BatchDeleter rcClient *rockscache.Client expireTime time.Duration } -func (g *minioCacheRedis) newCache() *minioCacheRedis { - return &minioCacheRedis{ - rcClient: g.rcClient, - expireTime: g.expireTime, - metaCache: NewMetaCacheRedis(g.rcClient, g.metaCache.GetPreDelKeys()...), - } +func (g *minioCacheRedis) getObjectImageInfoKey(key string) string { + return cachekey.GetObjectImageInfoKey(key) +} + +func (g *minioCacheRedis) getMinioImageThumbnailKey(key string, format string, width int, height int) string { + return cachekey.GetMinioImageThumbnailKey(key, format, width, height) } func (g *minioCacheRedis) DelObjectImageInfoKey(ctx context.Context, keys ...string) error { - s3cache := g.newCache() ks := make([]string, 0, len(keys)) for _, key := range keys { ks = append(ks, g.getObjectImageInfoKey(key)) } - s3cache.AddKeys(ks...) - return s3cache.ExecDel(ctx) + return g.BatchDeleter.ExecDelWithKeys(ctx, ks) } func (g *minioCacheRedis) DelImageThumbnailKey(ctx context.Context, key string, format string, width int, height int) error { - s3cache := g.newCache() - s3cache.AddKeys(g.getMinioImageThumbnailKey(key, format, width, height)) - return s3cache.ExecDel(ctx) -} + return g.BatchDeleter.ExecDelWithKeys(ctx, []string{g.getMinioImageThumbnailKey(key, format, width, height)}) -func (g *minioCacheRedis) getObjectImageInfoKey(key string) string { - return "MINIO:IMAGE:" + key -} - -func (g *minioCacheRedis) getMinioImageThumbnailKey(key string, format string, width int, height int) string { - return "MINIO:THUMBNAIL:" + format + ":w" + strconv.Itoa(width) + ":h" + strconv.Itoa(height) + ":" + key } func (g *minioCacheRedis) GetImageObjectKeyInfo(ctx context.Context, key string, fn func(ctx context.Context) (*minio.ImageInfo, error)) (*minio.ImageInfo, error) { @@ -197,11 +159,3 @@ func (g *minioCacheRedis) GetImageObjectKeyInfo(ctx context.Context, key string, func (g *minioCacheRedis) GetThumbnailKey(ctx context.Context, key string, format string, width int, height int, minioCache func(ctx context.Context) (string, error)) (string, error) { return getCache(ctx, g.rcClient, g.getMinioImageThumbnailKey(key, format, width, height), g.expireTime, minioCache) } - -type MinioImageInfo struct { - IsImg bool `json:"isImg"` - Width int `json:"width"` - Height int `json:"height"` - Format string `json:"format"` - Etag string `json:"etag"` -} diff --git a/pkg/common/db/cache/seq.go b/pkg/common/storage/cache/redis/seq.go similarity index 73% rename from pkg/common/db/cache/seq.go rename to pkg/common/storage/cache/redis/seq.go index 6fbb09183..76dd921a5 100644 --- a/pkg/common/db/cache/seq.go +++ b/pkg/common/storage/cache/redis/seq.go @@ -1,38 +1,29 @@ -package cache +// 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 redis import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/utils/stringutil" "github.com/redis/go-redis/v9" ) -type SeqCache interface { - SetMaxSeq(ctx context.Context, conversationID string, maxSeq int64) error - GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) - GetMaxSeq(ctx context.Context, conversationID string) (int64, error) - SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error - SetMinSeqs(ctx context.Context, seqs map[string]int64) error - GetMinSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) - GetMinSeq(ctx context.Context, conversationID string) (int64, error) - GetConversationUserMinSeq(ctx context.Context, conversationID string, userID string) (int64, error) - GetConversationUserMinSeqs(ctx context.Context, conversationID string, userIDs []string) (map[string]int64, error) - SetConversationUserMinSeq(ctx context.Context, conversationID string, userID string, minSeq int64) error - // seqs map: key userID value minSeq - SetConversationUserMinSeqs(ctx context.Context, conversationID string, seqs map[string]int64) (err error) - // seqs map: key conversationID value minSeq - SetUserConversationsMinSeqs(ctx context.Context, userID string, seqs map[string]int64) error - // has read seq - SetHasReadSeq(ctx context.Context, userID string, conversationID string, hasReadSeq int64) error - // k: user, v: seq - SetHasReadSeqs(ctx context.Context, conversationID string, hasReadSeqs map[string]int64) error - // k: conversation, v :seq - UserSetHasReadSeqs(ctx context.Context, userID string, hasReadSeqs map[string]int64) error - GetHasReadSeqs(ctx context.Context, userID string, conversationIDs []string) (map[string]int64, error) - GetHasReadSeq(ctx context.Context, userID string, conversationID string) (int64, error) -} - -func NewSeqCache(rdb redis.UniversalClient) SeqCache { +func NewSeqCache(rdb redis.UniversalClient) cache.SeqCache { return &seqCache{rdb: rdb} } @@ -41,19 +32,19 @@ type seqCache struct { } func (c *seqCache) getMaxSeqKey(conversationID string) string { - return maxSeq + conversationID + return cachekey.GetMaxSeqKey(conversationID) } func (c *seqCache) getMinSeqKey(conversationID string) string { - return minSeq + conversationID + return cachekey.GetMinSeqKey(conversationID) } func (c *seqCache) getHasReadSeqKey(conversationID string, userID string) string { - return hasReadSeq + userID + ":" + conversationID + return cachekey.GetHasReadSeqKey(conversationID, userID) } func (c *seqCache) getConversationUserMinSeqKey(conversationID, userID string) string { - return conversationUserMinSeq + conversationID + "u:" + userID + return cachekey.GetConversationUserMinSeqKey(conversationID, userID) } func (c *seqCache) setSeq(ctx context.Context, conversationID string, seq int64, getkey func(conversationID string) string) error { diff --git a/pkg/common/storage/cache/redis/third.go b/pkg/common/storage/cache/redis/third.go new file mode 100644 index 000000000..3288cecb8 --- /dev/null +++ b/pkg/common/storage/cache/redis/third.go @@ -0,0 +1,103 @@ +// 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 redis + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/tools/errs" + "github.com/redis/go-redis/v9" + "time" +) + +func NewThirdCache(rdb redis.UniversalClient) cache.ThirdCache { + return &thirdCache{rdb: rdb} +} + +type thirdCache struct { + rdb redis.UniversalClient +} + +func (c *thirdCache) getGetuiTokenKey() string { + return cachekey.GetGetuiTokenKey() +} + +func (c *thirdCache) getGetuiTaskIDKey() string { + return cachekey.GetGetuiTaskIDKey() +} + +func (c *thirdCache) getUserBadgeUnreadCountSumKey(userID string) string { + return cachekey.GetUserBadgeUnreadCountSumKey(userID) +} + +func (c *thirdCache) getFcmAccountTokenKey(account string, platformID int) string { + return cachekey.GetFcmAccountTokenKey(account, platformID) +} + +func (c *thirdCache) SetFcmToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) (err error) { + return errs.Wrap(c.rdb.Set(ctx, c.getFcmAccountTokenKey(account, platformID), fcmToken, time.Duration(expireTime)*time.Second).Err()) +} + +func (c *thirdCache) GetFcmToken(ctx context.Context, account string, platformID int) (string, error) { + val, err := c.rdb.Get(ctx, c.getFcmAccountTokenKey(account, platformID)).Result() + if err != nil { + return "", errs.Wrap(err) + } + return val, nil +} + +func (c *thirdCache) DelFcmToken(ctx context.Context, account string, platformID int) error { + return errs.Wrap(c.rdb.Del(ctx, c.getFcmAccountTokenKey(account, platformID)).Err()) +} + +func (c *thirdCache) IncrUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) { + seq, err := c.rdb.Incr(ctx, c.getUserBadgeUnreadCountSumKey(userID)).Result() + + return int(seq), errs.Wrap(err) +} + +func (c *thirdCache) SetUserBadgeUnreadCountSum(ctx context.Context, userID string, value int) error { + return errs.Wrap(c.rdb.Set(ctx, c.getUserBadgeUnreadCountSumKey(userID), value, 0).Err()) +} + +func (c *thirdCache) GetUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) { + val, err := c.rdb.Get(ctx, c.getUserBadgeUnreadCountSumKey(userID)).Int() + return val, errs.Wrap(err) +} + +func (c *thirdCache) SetGetuiToken(ctx context.Context, token string, expireTime int64) error { + return errs.Wrap(c.rdb.Set(ctx, c.getGetuiTokenKey(), token, time.Duration(expireTime)*time.Second).Err()) +} + +func (c *thirdCache) GetGetuiToken(ctx context.Context) (string, error) { + val, err := c.rdb.Get(ctx, c.getGetuiTokenKey()).Result() + if err != nil { + return "", errs.Wrap(err) + } + return val, nil +} + +func (c *thirdCache) SetGetuiTaskID(ctx context.Context, taskID string, expireTime int64) error { + return errs.Wrap(c.rdb.Set(ctx, c.getGetuiTaskIDKey(), taskID, time.Duration(expireTime)*time.Second).Err()) +} + +func (c *thirdCache) GetGetuiTaskID(ctx context.Context) (string, error) { + val, err := c.rdb.Get(ctx, c.getGetuiTaskIDKey()).Result() + if err != nil { + return "", errs.Wrap(err) + } + return val, nil +} diff --git a/pkg/common/db/cache/token.go b/pkg/common/storage/cache/redis/token.go similarity index 60% rename from pkg/common/db/cache/token.go rename to pkg/common/storage/cache/redis/token.go index 88580e932..6098a666c 100644 --- a/pkg/common/db/cache/token.go +++ b/pkg/common/storage/cache/redis/token.go @@ -1,31 +1,38 @@ -package cache +// 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 redis import ( "context" - - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/utils/stringutil" "github.com/redis/go-redis/v9" ) -func NewTokenCacheModel(rdb redis.UniversalClient) TokenModel { +type tokenCache struct { + rdb redis.UniversalClient +} + +func NewTokenCacheModel(rdb redis.UniversalClient) cache.TokenModel { return &tokenCache{ rdb: rdb, } } -type TokenModel interface { - AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error - GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error) - SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error - DeleteTokenByUidPid(ctx context.Context, userID string, platformID int, fields []string) error -} - -type tokenCache struct { - rdb redis.UniversalClient -} - func (c *tokenCache) AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error { return errs.Wrap(c.rdb.HSet(ctx, cachekey.GetTokenKey(userID, platformID), token, flag).Err()) } diff --git a/pkg/common/db/cache/user.go b/pkg/common/storage/cache/redis/user.go similarity index 78% rename from pkg/common/db/cache/user.go rename to pkg/common/storage/cache/redis/user.go index c10e9611a..3de01563b 100644 --- a/pkg/common/db/cache/user.go +++ b/pkg/common/storage/cache/redis/user.go @@ -12,78 +12,66 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package redis import ( "context" "encoding/json" "errors" - "hash/crc32" - "strconv" - "time" - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/log" "github.com/redis/go-redis/v9" + "hash/crc32" + "strconv" + "time" ) const ( userExpireTime = time.Second * 60 * 60 * 12 - olineStatusKey = "ONLINE_STATUS:" userOlineStatusExpireTime = time.Second * 60 * 60 * 24 statusMod = 501 ) -type UserCache interface { - metaCache - NewCache() UserCache - GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) - GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) - DelUsersInfo(userIDs ...string) UserCache - GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) - DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache - GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) - SetUserStatus(ctx context.Context, userID string, status, platformID int32) error -} - type UserCacheRedis struct { - metaCache - rdb redis.UniversalClient - // userDB relationtb.UserModelInterface - userDB relationtb.UserModelInterface + cache.BatchDeleter + rdb redis.UniversalClient + userDB database.User expireTime time.Duration rcClient *rockscache.Client } -func NewUserCacheRedis(rdb redis.UniversalClient, localCache *config.LocalCache, userDB relationtb.UserModelInterface, options rockscache.Options) UserCache { - rcClient := rockscache.NewClient(rdb, options) - mc := NewMetaCacheRedis(rcClient) +func NewUserCacheRedis(rdb redis.UniversalClient, localCache *config.LocalCache, userDB database.User, options *rockscache.Options) cache.UserCache { + batchHandler := NewBatchDeleterRedis(rdb, options, []string{localCache.User.Topic}) u := localCache.User log.ZDebug(context.Background(), "user local cache init", "Topic", u.Topic, "SlotNum", u.SlotNum, "SlotSize", u.SlotSize, "enable", u.Enable()) - mc.SetTopic(u.Topic) - mc.SetRawRedisClient(rdb) return &UserCacheRedis{ - rdb: rdb, - metaCache: NewMetaCacheRedis(rcClient), - userDB: userDB, - expireTime: userExpireTime, - rcClient: rcClient, + BatchDeleter: batchHandler, + rdb: rdb, + userDB: userDB, + expireTime: userExpireTime, + rcClient: rockscache.NewClient(rdb, *options), } } -func (u *UserCacheRedis) NewCache() UserCache { +func (u *UserCacheRedis) getOnlineStatusKey(modKey string) string { + return cachekey.GetOnlineStatusKey(modKey) +} + +func (u *UserCacheRedis) CloneUserCache() cache.UserCache { return &UserCacheRedis{ - rdb: u.rdb, - metaCache: u.Copy(), - userDB: u.userDB, - expireTime: u.expireTime, - rcClient: u.rcClient, + BatchDeleter: u.BatchDeleter.Clone(), + rdb: u.rdb, + userDB: u.userDB, + expireTime: u.expireTime, + rcClient: u.rcClient, } } @@ -95,26 +83,26 @@ func (u *UserCacheRedis) getUserGlobalRecvMsgOptKey(userID string) string { return cachekey.GetUserGlobalRecvMsgOptKey(userID) } -func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.UserModel, err error) { - return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*relationtb.UserModel, error) { +func (u *UserCacheRedis) GetUserInfo(ctx context.Context, userID string) (userInfo *model.User, err error) { + return getCache(ctx, u.rcClient, u.getUserInfoKey(userID), u.expireTime, func(ctx context.Context) (*model.User, error) { return u.userDB.Take(ctx, userID) }) } -func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.UserModel, error) { - return batchGetCache2(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string { +func (u *UserCacheRedis) GetUsersInfo(ctx context.Context, userIDs []string) ([]*model.User, error) { + return batchGetCache(ctx, u.rcClient, u.expireTime, userIDs, func(userID string) string { return u.getUserInfoKey(userID) - }, func(ctx context.Context, userID string) (*relationtb.UserModel, error) { + }, func(ctx context.Context, userID string) (*model.User, error) { return u.userDB.Take(ctx, userID) }) } -func (u *UserCacheRedis) DelUsersInfo(userIDs ...string) UserCache { +func (u *UserCacheRedis) DelUsersInfo(userIDs ...string) cache.UserCache { keys := make([]string, 0, len(userIDs)) for _, userID := range userIDs { keys = append(keys, u.getUserInfoKey(userID)) } - cache := u.NewCache() + cache := u.CloneUserCache() cache.AddKeys(keys...) return cache @@ -132,12 +120,12 @@ func (u *UserCacheRedis) GetUserGlobalRecvMsgOpt(ctx context.Context, userID str ) } -func (u *UserCacheRedis) DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache { +func (u *UserCacheRedis) DelUsersGlobalRecvMsgOpt(userIDs ...string) cache.UserCache { keys := make([]string, 0, len(userIDs)) for _, userID := range userIDs { keys = append(keys, u.getUserGlobalRecvMsgOptKey(userID)) } - cache := u.NewCache() + cache := u.CloneUserCache() cache.AddKeys(keys...) return cache @@ -150,7 +138,7 @@ func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([ UserIDNum := crc32.ChecksumIEEE([]byte(userID)) modKey := strconv.Itoa(int(UserIDNum % statusMod)) var onlineStatus user.OnlineStatus - key := olineStatusKey + modKey + key := u.getOnlineStatusKey(modKey) result, err := u.rdb.HGet(ctx, key, userID).Result() if err != nil { if errors.Is(err, redis.Nil) { @@ -182,7 +170,7 @@ func (u *UserCacheRedis) GetUserStatus(ctx context.Context, userIDs []string) ([ func (u *UserCacheRedis) SetUserStatus(ctx context.Context, userID string, status, platformID int32) error { UserIDNum := crc32.ChecksumIEEE([]byte(userID)) modKey := strconv.Itoa(int(UserIDNum % statusMod)) - key := olineStatusKey + modKey + key := u.getOnlineStatusKey(modKey) log.ZDebug(ctx, "SetUserStatus args", "userID", userID, "status", status, "platformID", platformID, "modKey", modKey, "key", key) isNewKey, err := u.rdb.Exists(ctx, key).Result() if err != nil { diff --git a/pkg/common/storage/cache/s3.go b/pkg/common/storage/cache/s3.go new file mode 100644 index 000000000..4d899586c --- /dev/null +++ b/pkg/common/storage/cache/s3.go @@ -0,0 +1,51 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cache + +import ( + "context" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/tools/s3" +) + +type ObjectCache interface { + BatchDeleter + CloneObjectCache() ObjectCache + GetName(ctx context.Context, engine string, name string) (*relationtb.Object, error) + DelObjectName(engine string, names ...string) ObjectCache +} + +type S3Cache interface { + BatchDeleter + GetKey(ctx context.Context, engine string, key string) (*s3.ObjectInfo, error) + DelS3Key(engine string, keys ...string) S3Cache +} + +// TODO integrating minio.Cache and MinioCache interfaces. +type MinioCache interface { + BatchDeleter + GetImageObjectKeyInfo(ctx context.Context, key string, fn func(ctx context.Context) (*MinioImageInfo, error)) (*MinioImageInfo, error) + GetThumbnailKey(ctx context.Context, key string, format string, width int, height int, minioCache func(ctx context.Context) (string, error)) (string, error) + DelObjectImageInfoKey(keys ...string) MinioCache + DelImageThumbnailKey(key string, format string, width int, height int) MinioCache +} + +type MinioImageInfo struct { + IsImg bool `json:"isImg"` + Width int `json:"width"` + Height int `json:"height"` + Format string `json:"format"` + Etag string `json:"etag"` +} diff --git a/pkg/common/storage/cache/seq.go b/pkg/common/storage/cache/seq.go new file mode 100644 index 000000000..091b318c8 --- /dev/null +++ b/pkg/common/storage/cache/seq.go @@ -0,0 +1,30 @@ +package cache + +import ( + "context" +) + +type SeqCache interface { + SetMaxSeq(ctx context.Context, conversationID string, maxSeq int64) error + GetMaxSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) + GetMaxSeq(ctx context.Context, conversationID string) (int64, error) + SetMinSeq(ctx context.Context, conversationID string, minSeq int64) error + SetMinSeqs(ctx context.Context, seqs map[string]int64) error + GetMinSeqs(ctx context.Context, conversationIDs []string) (map[string]int64, error) + GetMinSeq(ctx context.Context, conversationID string) (int64, error) + GetConversationUserMinSeq(ctx context.Context, conversationID string, userID string) (int64, error) + GetConversationUserMinSeqs(ctx context.Context, conversationID string, userIDs []string) (map[string]int64, error) + SetConversationUserMinSeq(ctx context.Context, conversationID string, userID string, minSeq int64) error + // seqs map: key userID value minSeq + SetConversationUserMinSeqs(ctx context.Context, conversationID string, seqs map[string]int64) (err error) + // seqs map: key conversationID value minSeq + SetUserConversationsMinSeqs(ctx context.Context, userID string, seqs map[string]int64) error + // has read seq + SetHasReadSeq(ctx context.Context, userID string, conversationID string, hasReadSeq int64) error + // k: user, v: seq + SetHasReadSeqs(ctx context.Context, conversationID string, hasReadSeqs map[string]int64) error + // k: conversation, v :seq + UserSetHasReadSeqs(ctx context.Context, userID string, hasReadSeqs map[string]int64) error + GetHasReadSeqs(ctx context.Context, userID string, conversationIDs []string) (map[string]int64, error) + GetHasReadSeq(ctx context.Context, userID string, conversationID string) (int64, error) +} diff --git a/pkg/common/storage/cache/third.go b/pkg/common/storage/cache/third.go new file mode 100644 index 000000000..ba6d04061 --- /dev/null +++ b/pkg/common/storage/cache/third.go @@ -0,0 +1,18 @@ +package cache + +import ( + "context" +) + +type ThirdCache interface { + SetFcmToken(ctx context.Context, account string, platformID int, fcmToken string, expireTime int64) (err error) + GetFcmToken(ctx context.Context, account string, platformID int) (string, error) + DelFcmToken(ctx context.Context, account string, platformID int) error + IncrUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) + SetUserBadgeUnreadCountSum(ctx context.Context, userID string, value int) error + GetUserBadgeUnreadCountSum(ctx context.Context, userID string) (int, error) + SetGetuiToken(ctx context.Context, token string, expireTime int64) error + GetGetuiToken(ctx context.Context) (string, error) + SetGetuiTaskID(ctx context.Context, taskID string, expireTime int64) error + GetGetuiTaskID(ctx context.Context) (string, error) +} diff --git a/pkg/common/storage/cache/token.go b/pkg/common/storage/cache/token.go new file mode 100644 index 000000000..55b3321ef --- /dev/null +++ b/pkg/common/storage/cache/token.go @@ -0,0 +1,12 @@ +package cache + +import ( + "context" +) + +type TokenModel interface { + AddTokenFlag(ctx context.Context, userID string, platformID int, token string, flag int) error + GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error) + SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error + DeleteTokenByUidPid(ctx context.Context, userID string, platformID int, fields []string) error +} diff --git a/pkg/common/storage/cache/user.go b/pkg/common/storage/cache/user.go new file mode 100644 index 000000000..4a129ddd1 --- /dev/null +++ b/pkg/common/storage/cache/user.go @@ -0,0 +1,33 @@ +// 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 cache + +import ( + "context" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/protocol/user" +) + +type UserCache interface { + BatchDeleter + CloneUserCache() UserCache + GetUserInfo(ctx context.Context, userID string) (userInfo *relationtb.User, err error) + GetUsersInfo(ctx context.Context, userIDs []string) ([]*relationtb.User, error) + DelUsersInfo(userIDs ...string) UserCache + GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) + DelUsersGlobalRecvMsgOpt(userIDs ...string) UserCache + GetUserStatus(ctx context.Context, userIDs []string) ([]*user.OnlineStatus, error) + SetUserStatus(ctx context.Context, userID string, status, platformID int32) error +} diff --git a/pkg/common/storage/common/types.go b/pkg/common/storage/common/types.go new file mode 100644 index 000000000..759121158 --- /dev/null +++ b/pkg/common/storage/common/types.go @@ -0,0 +1,26 @@ +// 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 common + +type BatchUpdateGroupMember struct { + GroupID string + UserID string + Map map[string]any +} + +type GroupSimpleUserID struct { + Hash uint64 + MemberNum uint32 +} diff --git a/pkg/common/db/controller/auth.go b/pkg/common/storage/controller/auth.go similarity index 97% rename from pkg/common/db/controller/auth.go rename to pkg/common/storage/controller/auth.go index 8190e5017..321583743 100644 --- a/pkg/common/db/controller/auth.go +++ b/pkg/common/storage/controller/auth.go @@ -19,7 +19,7 @@ import ( "github.com/golang-jwt/jwt/v4" "github.com/openimsdk/open-im-server/v3/pkg/authverify" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/errs" "github.com/openimsdk/tools/tokenverify" diff --git a/pkg/common/db/controller/black.go b/pkg/common/storage/controller/black.go similarity index 75% rename from pkg/common/db/controller/black.go rename to pkg/common/storage/controller/black.go index 5991a9dfe..8a12f2aa2 100644 --- a/pkg/common/db/controller/black.go +++ b/pkg/common/storage/controller/black.go @@ -16,9 +16,9 @@ package controller import ( "context" - - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/log" "github.com/openimsdk/tools/utils/datautil" @@ -26,27 +26,27 @@ import ( type BlackDatabase interface { // Create add BlackList - Create(ctx context.Context, blacks []*relation.BlackModel) (err error) + Create(ctx context.Context, blacks []*model.Black) (err error) // Delete delete BlackList - Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) + Delete(ctx context.Context, blacks []*model.Black) (err error) // FindOwnerBlacks get BlackList list - 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) + FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*model.Black, err error) + FindBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*model.Black, err error) // CheckIn Check whether user2 is in the black list of user1 (inUser1Blacks==true) Check whether user1 is in the black list of user2 (inUser2Blacks==true) CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Blacks bool, inUser2Blacks bool, err error) } type blackDatabase struct { - black relation.BlackModelInterface + black database.Black cache cache.BlackCache } -func NewBlackDatabase(black relation.BlackModelInterface, cache cache.BlackCache) BlackDatabase { +func NewBlackDatabase(black database.Black, cache cache.BlackCache) BlackDatabase { return &blackDatabase{black, cache} } // Create Add Blacklist. -func (b *blackDatabase) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) { +func (b *blackDatabase) Create(ctx context.Context, blacks []*model.Black) (err error) { if err := b.black.Create(ctx, blacks); err != nil { return err } @@ -54,7 +54,7 @@ func (b *blackDatabase) Create(ctx context.Context, blacks []*relation.BlackMode } // Delete Delete Blacklist. -func (b *blackDatabase) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) { +func (b *blackDatabase) Delete(ctx context.Context, blacks []*model.Black) (err error) { if err := b.black.Delete(ctx, blacks); err != nil { return err } @@ -62,16 +62,16 @@ func (b *blackDatabase) Delete(ctx context.Context, blacks []*relation.BlackMode } // FindOwnerBlacks Get Blacklist List. -func (b *blackDatabase) deleteBlackIDsCache(ctx context.Context, blacks []*relation.BlackModel) (err error) { - cache := b.cache.NewCache() +func (b *blackDatabase) deleteBlackIDsCache(ctx context.Context, blacks []*model.Black) (err error) { + cache := b.cache.CloneBlackCache() for _, black := range blacks { cache = cache.DelBlackIDs(ctx, black.OwnerUserID) } - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) } // FindOwnerBlacks Get Blacklist List. -func (b *blackDatabase) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) { +func (b *blackDatabase) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*model.Black, err error) { return b.black.FindOwnerBlacks(ctx, ownerUserID, pagination) } @@ -95,6 +95,6 @@ func (b *blackDatabase) FindBlackIDs(ctx context.Context, ownerUserID string) (b } // FindBlackInfos Get Blacklist List. -func (b *blackDatabase) FindBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) { +func (b *blackDatabase) FindBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*model.Black, err error) { return b.black.FindOwnerBlackInfos(ctx, ownerUserID, userIDs) } diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/storage/controller/conversation.go similarity index 86% rename from pkg/common/db/controller/conversation.go rename to pkg/common/storage/controller/conversation.go index 567bcb270..18ef3f8ba 100644 --- a/pkg/common/db/controller/conversation.go +++ b/pkg/common/storage/controller/conversation.go @@ -16,10 +16,11 @@ package controller import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/open-im-server/v3/pkg/msgprocessor" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/pagination" @@ -33,18 +34,18 @@ type ConversationDatabase interface { // UpdateUsersConversationField updates the properties of a conversation for specified users. UpdateUsersConversationField(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error // CreateConversation creates a batch of new conversations. - CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error + CreateConversation(ctx context.Context, conversations []*relationtb.Conversation) error // SyncPeerUserPrivateConversationTx ensures transactional operation while syncing private conversations between peers. - SyncPeerUserPrivateConversationTx(ctx context.Context, conversation []*relationtb.ConversationModel) error + SyncPeerUserPrivateConversationTx(ctx context.Context, conversation []*relationtb.Conversation) error // FindConversations retrieves multiple conversations of a user by conversation IDs. - FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) + FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.Conversation, error) // GetUserAllConversation fetches all conversations of a user on the server. - GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) + GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.Conversation, error) // SetUserConversations sets multiple conversation properties for a user, creates new conversations if they do not exist, or updates them otherwise. This operation is atomic. - SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error + SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.Conversation) error // SetUsersConversationFieldTx updates a specific field for multiple users' conversations, creating new conversations if they do not exist, or updates them otherwise. This operation is // transactional. - SetUsersConversationFieldTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, fieldMap map[string]any) error + SetUsersConversationFieldTx(ctx context.Context, userIDs []string, conversation *relationtb.Conversation, fieldMap map[string]any) error // CreateGroupChatConversation creates a group chat conversation for the specified group ID and user IDs. CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error // GetConversationIDs retrieves conversation IDs for a given user. @@ -58,16 +59,16 @@ type ConversationDatabase interface { // PageConversationIDs paginates through conversation IDs based on the specified pagination settings. PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) // GetConversationsByConversationID retrieves conversations by their IDs. - GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) + GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.Conversation, error) // GetConversationIDsNeedDestruct fetches conversations that need to be destructed based on specific criteria. - GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error) + GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.Conversation, error) // GetConversationNotReceiveMessageUserIDs gets user IDs for users in a conversation who have not received messages. GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) // GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) // FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) } -func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase { +func NewConversationDatabase(conversation database.Conversation, cache cache.ConversationCache, tx tx.Tx) ConversationDatabase { return &conversationDatabase{ conversationDB: conversation, cache: cache, @@ -76,14 +77,14 @@ func NewConversationDatabase(conversation relationtb.ConversationModelInterface, } type conversationDatabase struct { - conversationDB relationtb.ConversationModelInterface + conversationDB database.Conversation cache cache.ConversationCache tx tx.Tx } -func (c *conversationDatabase) SetUsersConversationFieldTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, fieldMap map[string]any) (err error) { +func (c *conversationDatabase) SetUsersConversationFieldTx(ctx context.Context, userIDs []string, conversation *relationtb.Conversation, fieldMap map[string]any) (err error) { return c.tx.Transaction(ctx, func(ctx context.Context) error { - cache := c.cache.NewCache() + cache := c.cache.CloneConversationCache() if conversation.GroupID != "" { cache = cache.DelSuperGroupRecvMsgNotNotifyUserIDs(conversation.GroupID).DelSuperGroupRecvMsgNotNotifyUserIDsHash(conversation.GroupID) } @@ -108,10 +109,10 @@ func (c *conversationDatabase) SetUsersConversationFieldTx(ctx context.Context, } NotUserIDs := stringutil.DifferenceString(haveUserIDs, userIDs) log.ZDebug(ctx, "SetUsersConversationFieldTx", "NotUserIDs", NotUserIDs, "haveUserIDs", haveUserIDs, "userIDs", userIDs) - var conversations []*relationtb.ConversationModel + var conversations []*relationtb.Conversation now := time.Now() for _, v := range NotUserIDs { - temp := new(relationtb.ConversationModel) + temp := new(relationtb.Conversation) if err = datautil.CopyStructFields(temp, conversation); err != nil { return err } @@ -126,7 +127,7 @@ func (c *conversationDatabase) SetUsersConversationFieldTx(ctx context.Context, } cache = cache.DelConversationIDs(NotUserIDs...).DelUserConversationIDsHash(NotUserIDs...).DelConversations(conversation.ConversationID, NotUserIDs...) } - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) }) } @@ -135,31 +136,31 @@ func (c *conversationDatabase) UpdateUsersConversationField(ctx context.Context, if err != nil { return err } - cache := c.cache.NewCache() + cache := c.cache.CloneConversationCache() cache = cache.DelUsersConversation(conversationID, userIDs...) if _, ok := args["recv_msg_opt"]; ok { cache = cache.DelConversationNotReceiveMessageUserIDs(conversationID) } - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) } -func (c *conversationDatabase) CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error { +func (c *conversationDatabase) CreateConversation(ctx context.Context, conversations []*relationtb.Conversation) error { if err := c.conversationDB.Create(ctx, conversations); err != nil { return err } var userIDs []string - cache := c.cache.NewCache() + cache := c.cache.CloneConversationCache() for _, conversation := range conversations { cache = cache.DelConversations(conversation.OwnerUserID, conversation.ConversationID) cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID) userIDs = append(userIDs, conversation.OwnerUserID) } - return cache.DelConversationIDs(userIDs...).DelUserConversationIDsHash(userIDs...).ExecDel(ctx) + return cache.DelConversationIDs(userIDs...).DelUserConversationIDsHash(userIDs...).ChainExecDel(ctx) } -func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.ConversationModel) error { +func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Context, conversations []*relationtb.Conversation) error { return c.tx.Transaction(ctx, func(ctx context.Context) error { - cache := c.cache.NewCache() + cache := c.cache.CloneConversationCache() for _, conversation := range conversations { for _, v := range [][2]string{{conversation.OwnerUserID, conversation.UserID}, {conversation.UserID, conversation.OwnerUserID}} { ownerUserID := v[0] @@ -180,33 +181,33 @@ func (c *conversationDatabase) SyncPeerUserPrivateConversationTx(ctx context.Con newConversation.UserID = userID newConversation.ConversationID = conversation.ConversationID newConversation.IsPrivateChat = conversation.IsPrivateChat - if err := c.conversationDB.Create(ctx, []*relationtb.ConversationModel{&newConversation}); err != nil { + if err := c.conversationDB.Create(ctx, []*relationtb.Conversation{&newConversation}); err != nil { return err } cache = cache.DelConversationIDs(ownerUserID).DelUserConversationIDsHash(ownerUserID) } } } - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) }) } -func (c *conversationDatabase) FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) { +func (c *conversationDatabase) FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.Conversation, error) { return c.cache.GetConversations(ctx, ownerUserID, conversationIDs) } -func (c *conversationDatabase) GetConversation(ctx context.Context, ownerUserID string, conversationID string) (*relationtb.ConversationModel, error) { +func (c *conversationDatabase) GetConversation(ctx context.Context, ownerUserID string, conversationID string) (*relationtb.Conversation, error) { return c.cache.GetConversation(ctx, ownerUserID, conversationID) } -func (c *conversationDatabase) GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) { +func (c *conversationDatabase) GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.Conversation, error) { return c.cache.GetUserAllConversations(ctx, ownerUserID) } -func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error { +func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.Conversation) error { return c.tx.Transaction(ctx, func(ctx context.Context) error { - cache := c.cache.NewCache() - groupIDs := datautil.Distinct(datautil.Filter(conversations, func(e *relationtb.ConversationModel) (string, bool) { + cache := c.cache.CloneConversationCache() + groupIDs := datautil.Distinct(datautil.Filter(conversations, func(e *relationtb.Conversation) (string, bool) { return e.GroupID, e.GroupID != "" })) for _, groupID := range groupIDs { @@ -234,7 +235,7 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs existConversationIDs = append(existConversationIDs, conversation.ConversationID) } - var notExistConversations []*relationtb.ConversationModel + var notExistConversations []*relationtb.Conversation for _, conversation := range conversations { if !datautil.Contain(conversation.ConversationID, existConversationIDs...) { notExistConversations = append(notExistConversations, conversation) @@ -247,9 +248,9 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs } cache = cache.DelConversationIDs(ownerUserID). DelUserConversationIDsHash(ownerUserID). - DelConversationNotReceiveMessageUserIDs(datautil.Slice(notExistConversations, func(e *relationtb.ConversationModel) string { return e.ConversationID })...) + DelConversationNotReceiveMessageUserIDs(datautil.Slice(notExistConversations, func(e *relationtb.Conversation) string { return e.ConversationID })...) } - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) }) } @@ -259,16 +260,16 @@ func (c *conversationDatabase) SetUserConversations(ctx context.Context, ownerUs func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error { return c.tx.Transaction(ctx, func(ctx context.Context) error { - cache := c.cache.NewCache() + cache := c.cache.CloneConversationCache() conversationID := msgprocessor.GetConversationIDBySessionType(constant.ReadGroupChatType, groupID) existConversationUserIDs, err := c.conversationDB.FindUserID(ctx, userIDs, []string{conversationID}) if err != nil { return err } notExistUserIDs := stringutil.DifferenceString(userIDs, existConversationUserIDs) - var conversations []*relationtb.ConversationModel + var conversations []*relationtb.Conversation for _, v := range notExistUserIDs { - conversation := relationtb.ConversationModel{ConversationType: constant.ReadGroupChatType, GroupID: groupID, OwnerUserID: v, ConversationID: conversationID} + conversation := relationtb.Conversation{ConversationType: constant.ReadGroupChatType, GroupID: groupID, OwnerUserID: v, ConversationID: conversationID} conversations = append(conversations, &conversation) cache = cache.DelConversations(v, conversationID).DelConversationNotReceiveMessageUserIDs(conversationID) } @@ -286,7 +287,7 @@ func (c *conversationDatabase) CreateGroupChatConversation(ctx context.Context, for _, v := range existConversationUserIDs { cache = cache.DelConversations(v, conversationID) } - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) }) } @@ -310,11 +311,11 @@ func (c *conversationDatabase) PageConversationIDs(ctx context.Context, paginati return c.conversationDB.PageConversationIDs(ctx, pagination) } -func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) { +func (c *conversationDatabase) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.Conversation, error) { return c.conversationDB.GetConversationsByConversationID(ctx, conversationIDs) } -func (c *conversationDatabase) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error) { +func (c *conversationDatabase) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.Conversation, error) { return c.conversationDB.GetConversationIDsNeedDestruct(ctx) } diff --git a/pkg/common/db/controller/doc.go b/pkg/common/storage/controller/doc.go similarity index 94% rename from pkg/common/db/controller/doc.go rename to pkg/common/storage/controller/doc.go index 97ec08799..8ade2b13a 100644 --- a/pkg/common/db/controller/doc.go +++ b/pkg/common/storage/controller/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package controller // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/controller" +package controller // import "github.com/openimsdk/open-im-server/v3/pkg/common/storage/controller" diff --git a/pkg/common/db/controller/friend.go b/pkg/common/storage/controller/friend.go similarity index 82% rename from pkg/common/db/controller/friend.go rename to pkg/common/storage/controller/friend.go index 49136f228..1c3d9f139 100644 --- a/pkg/common/db/controller/friend.go +++ b/pkg/common/storage/controller/friend.go @@ -17,10 +17,12 @@ package controller import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database/mgo" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/db/tx" @@ -37,14 +39,14 @@ type FriendDatabase interface { // AddFriendRequest adds or updates a friend request AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) - // BecomeFriends first checks if the users are already in the friends table; if not, it inserts them as friends + // BecomeFriends first checks if the users are already in the friends model; if not, it inserts them as friends BecomeFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, addSource int32) (err error) // RefuseFriendRequest refuses a friend request - RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) + RefuseFriendRequest(ctx context.Context, friendRequest *model.FriendRequest) (err error) // AgreeFriendRequest accepts a friend request - AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) + AgreeFriendRequest(ctx context.Context, friendRequest *model.FriendRequest) (err error) // Delete removes a friend or friends from the owner's friend list Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) @@ -53,38 +55,38 @@ type FriendDatabase interface { UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) // PageOwnerFriends retrieves the friend list of ownerUserID with pagination - PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) + PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error) // PageInWhoseFriends finds the users who have friendUserID in their friend list with pagination - PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) + PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error) // PageFriendRequestFromMe retrieves the friend requests sent by the user with pagination - PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) + PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) // PageFriendRequestToMe retrieves the friend requests received by the user with pagination - PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) + PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) // FindFriendsWithError fetches specified friends of a user and returns an error if any do not exist - FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) + FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*model.Friend, err error) // FindFriendUserIDs retrieves the friend IDs of a user FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) // FindBothFriendRequests finds friend requests sent and received - FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) + FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) // UpdateFriends updates fields for friends UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error) } type friendDatabase struct { - friend relation.FriendModelInterface - friendRequest relation.FriendRequestModelInterface + friend database.Friend + friendRequest database.FriendRequest tx tx.Tx cache cache.FriendCache } -func NewFriendDatabase(friend relation.FriendModelInterface, friendRequest relation.FriendRequestModelInterface, cache cache.FriendCache, tx tx.Tx) FriendDatabase { +func NewFriendDatabase(friend database.Friend, friendRequest database.FriendRequest, cache cache.FriendCache, tx tx.Tx) FriendDatabase { return &friendDatabase{friend: friend, friendRequest: friendRequest, cache: cache, tx: tx} } @@ -124,10 +126,10 @@ func (f *friendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUse m["ex"] = ex m["create_time"] = time.Now() return f.friendRequest.UpdateByMap(ctx, fromUserID, toUserID, m) - case relation.IsNotFound(err): + case mgo.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)}}, + []*model.FriendRequest{{FromUserID: fromUserID, ToUserID: toUserID, ReqMsg: reqMsg, Ex: ex, CreateTime: time.Now(), HandleTime: time.Unix(0, 0)}}, ) default: return err @@ -138,7 +140,7 @@ func (f *friendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUse // (1) First determine whether it is in the friends list (in or out does not return an error) (2) for not in the friends list can be inserted. 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() + cache := f.cache.CloneFriendCache() // user find friends fs1, err := f.friend.FindFriends(ctx, ownerUserID, friendUserIDs) if err != nil { @@ -146,9 +148,9 @@ func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string, } opUserID := mcontext.GetOperationID(ctx) for _, v := range friendUserIDs { - fs1 = append(fs1, &relation.FriendModel{OwnerUserID: ownerUserID, FriendUserID: v, AddSource: addSource, OperatorUserID: opUserID}) + fs1 = append(fs1, &model.Friend{OwnerUserID: ownerUserID, FriendUserID: v, AddSource: addSource, OperatorUserID: opUserID}) } - fs11 := datautil.DistinctAny(fs1, func(e *relation.FriendModel) string { + fs11 := datautil.DistinctAny(fs1, func(e *model.Friend) string { return e.FriendUserID }) @@ -162,10 +164,10 @@ func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string, } var newFriendIDs []string for _, v := range friendUserIDs { - fs2 = append(fs2, &relation.FriendModel{OwnerUserID: v, FriendUserID: ownerUserID, AddSource: addSource, OperatorUserID: opUserID}) + fs2 = append(fs2, &model.Friend{OwnerUserID: v, FriendUserID: ownerUserID, AddSource: addSource, OperatorUserID: opUserID}) newFriendIDs = append(newFriendIDs, v) } - fs22 := datautil.DistinctAny(fs2, func(e *relation.FriendModel) string { + fs22 := datautil.DistinctAny(fs2, func(e *model.Friend) string { return e.OwnerUserID }) err = f.friend.Create(ctx, fs22) @@ -174,14 +176,14 @@ func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string, } newFriendIDs = append(newFriendIDs, ownerUserID) cache = cache.DelFriendIDs(newFriendIDs...) - return cache.ExecDel(ctx) + return cache.ChainExecDel(ctx) }) } // RefuseFriendRequest rejects a friend request. It first checks for an existing, unprocessed request. // If no such request exists, it returns an error. Otherwise, it marks the request as refused. -func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) error { +func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *model.FriendRequest) error { // Attempt to retrieve the friend request from the database. fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID) if err != nil { @@ -210,7 +212,7 @@ func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest } // AgreeFriendRequest accepts a friend request. It first checks for an existing, unprocessed request. -func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { +func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *model.FriendRequest) (err error) { return f.tx.Transaction(ctx, func(ctx context.Context) error { now := time.Now() fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID) @@ -237,7 +239,7 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * if err != nil { return err } - } else if err != nil && (!relation.IsNotFound(err)) { + } else if err != nil && (!mgo.IsNotFound(err)) { return err } @@ -245,14 +247,14 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * if err != nil { return err } - existsMap := datautil.SliceSet(datautil.Slice(exists, func(friend *relation.FriendModel) [2]string { + existsMap := datautil.SliceSet(datautil.Slice(exists, func(friend *model.Friend) [2]string { return [...]string{friend.OwnerUserID, friend.FriendUserID} // My - Friend })) - var adds []*relation.FriendModel + var adds []*model.Friend if _, ok := existsMap[[...]string{friendRequest.ToUserID, friendRequest.FromUserID}]; !ok { // My - Friend adds = append( adds, - &relation.FriendModel{ + &model.Friend{ OwnerUserID: friendRequest.ToUserID, FriendUserID: friendRequest.FromUserID, AddSource: int32(constant.BecomeFriendByApply), @@ -263,7 +265,7 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * if _, ok := existsMap[[...]string{friendRequest.FromUserID, friendRequest.ToUserID}]; !ok { // My - Friend adds = append( adds, - &relation.FriendModel{ + &model.Friend{ OwnerUserID: friendRequest.FromUserID, FriendUserID: friendRequest.ToUserID, AddSource: int32(constant.BecomeFriendByApply), @@ -276,7 +278,7 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * return err } } - return f.cache.DelFriendIDs(friendRequest.ToUserID, friendRequest.FromUserID).ExecDel(ctx) + return f.cache.DelFriendIDs(friendRequest.ToUserID, friendRequest.FromUserID).ChainExecDel(ctx) }) } @@ -285,7 +287,7 @@ func (f *friendDatabase) Delete(ctx context.Context, ownerUserID string, friendU if err := f.friend.Delete(ctx, ownerUserID, friendUserIDs); err != nil { return err } - return f.cache.DelFriendIDs(append(friendUserIDs, ownerUserID)...).ExecDel(ctx) + return f.cache.DelFriendIDs(append(friendUserIDs, ownerUserID)...).ChainExecDel(ctx) } // UpdateRemark updates the remark for a friend. Zero value for remark is also supported. @@ -293,31 +295,31 @@ func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs if err := f.friend.UpdateRemark(ctx, ownerUserID, friendUserID, remark); err != nil { return err } - return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx) + return f.cache.DelFriend(ownerUserID, friendUserID).ChainExecDel(ctx) } // PageOwnerFriends retrieves the list of friends for the ownerUserID. It does not return an error if the result is empty. -func (f *friendDatabase) PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) { +func (f *friendDatabase) PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error) { return f.friend.FindOwnerFriends(ctx, ownerUserID, pagination) } // PageInWhoseFriends identifies in whose friend lists the friendUserID appears. -func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) { +func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error) { return f.friend.FindInWhoseFriends(ctx, friendUserID, pagination) } // PageFriendRequestFromMe retrieves friend requests sent by me. It does not return an error if the result is empty. -func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) { +func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) { return f.friendRequest.FindFromUserID(ctx, userID, pagination) } // PageFriendRequestToMe retrieves friend requests received by me. It does not return an error if the result is empty. -func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) { +func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*model.FriendRequest, err error) { return f.friendRequest.FindToUserID(ctx, userID, pagination) } // FindFriendsWithError retrieves specified friends' information for ownerUserID. Returns an error if any friend does not exist. -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 []*model.Friend, err error) { friends, err = f.friend.FindFriends(ctx, ownerUserID, friendUserIDs) if err != nil { return @@ -332,7 +334,7 @@ func (f *friendDatabase) FindFriendUserIDs(ctx context.Context, ownerUserID stri return f.cache.GetFriendIDs(ctx, ownerUserID) } -func (f *friendDatabase) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) { +func (f *friendDatabase) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) { return f.friendRequest.FindBothFriendRequests(ctx, fromUserID, toUserID) } func (f *friendDatabase) UpdateFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, val map[string]any) (err error) { @@ -342,5 +344,5 @@ func (f *friendDatabase) UpdateFriends(ctx context.Context, ownerUserID string, if err := f.friend.UpdateFriends(ctx, ownerUserID, friendUserIDs, val); err != nil { return err } - return f.cache.DelFriends(ownerUserID, friendUserIDs).ExecDel(ctx) + return f.cache.DelFriends(ownerUserID, friendUserIDs).ChainExecDel(ctx) } diff --git a/pkg/common/db/controller/group.go b/pkg/common/storage/controller/group.go similarity index 77% rename from pkg/common/db/controller/group.go rename to pkg/common/storage/controller/group.go index ddf72b7bf..f2a135835 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/storage/controller/group.go @@ -17,11 +17,13 @@ package controller import ( "context" "github.com/openimsdk/open-im-server/v3/pkg/common/config" + redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/common" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/dtm-labs/rockscache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - relationtb "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/db/tx" @@ -31,32 +33,32 @@ import ( type GroupDatabase interface { // CreateGroup creates new groups along with their members. - CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error + CreateGroup(ctx context.Context, groups []*model.Group, groupMembers []*model.GroupMember) error // TakeGroup retrieves a single group by its ID. - TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) + TakeGroup(ctx context.Context, groupID string) (group *model.Group, err error) // FindGroup retrieves multiple groups by their IDs. - FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) + FindGroup(ctx context.Context, groupIDs []string) (groups []*model.Group, err error) // SearchGroup searches for groups based on a keyword and pagination settings, returns total count and groups. - SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) + SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*model.Group, error) // UpdateGroup updates the properties of a group identified by its ID. UpdateGroup(ctx context.Context, groupID string, data map[string]any) error // DismissGroup disbands a group and optionally removes its members based on the deleteMember flag. DismissGroup(ctx context.Context, groupID string, deleteMember bool) error // TakeGroupMember retrieves a specific group member by group ID and user ID. - TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationtb.GroupMemberModel, err error) + TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *model.GroupMember, err error) // TakeGroupOwner retrieves the owner of a group by group ID. - TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) + TakeGroupOwner(ctx context.Context, groupID string) (*model.GroupMember, error) // FindGroupMembers retrieves members of a group filtered by user IDs. - FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*relationtb.GroupMemberModel, err error) + FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*model.GroupMember, err error) // FindGroupMemberUser retrieves groups that a user is a member of, filtered by group IDs. - FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*relationtb.GroupMemberModel, err error) + FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*model.GroupMember, err error) // FindGroupMemberRoleLevels retrieves group members filtered by their role levels within a group. - FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*relationtb.GroupMemberModel, err error) + FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*model.GroupMember, err error) // FindGroupMemberAll retrieves all members of a group. - FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) + FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*model.GroupMember, err error) // FindGroupsOwner retrieves the owners for multiple groups. - FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) + FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*model.GroupMember, error) // FindGroupMemberUserID retrieves the user IDs of all members in a group. FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) // FindGroupMemberNum retrieves the number of members in a group. @@ -64,22 +66,22 @@ type GroupDatabase interface { // FindUserManagedGroupID retrieves group IDs managed by a user. FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) // PageGroupRequest paginates through group requests for specified groups. - PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) + PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) // GetGroupRoleLevelMemberIDs retrieves user IDs of group members with a specific role level. GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) // PageGetJoinGroup paginates through groups that a user has joined. - PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) + PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*model.GroupMember, err error) // PageGetGroupMember paginates through members of a group. - PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) + PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*model.GroupMember, err error) // SearchGroupMember searches for group members based on a keyword, group ID, and pagination settings. - SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) + SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*model.GroupMember, error) // HandlerGroupRequest processes a group join request with a specified result. - HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error + HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *model.GroupMember) error // DeleteGroupMember removes specified users from a group. DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error // MapGroupMemberUserID maps group IDs to their members' simplified user IDs. - MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) + MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*common.GroupSimpleUserID, error) // MapGroupMemberNum maps group IDs to their member count. MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) // TransferGroupOwner transfers the ownership of a group to another user. @@ -87,16 +89,16 @@ type GroupDatabase interface { // UpdateGroupMember updates properties of a group member. UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error // UpdateGroupMembers batch updates properties of group members. - UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error + UpdateGroupMembers(ctx context.Context, data []*common.BatchUpdateGroupMember) error // CreateGroupRequest creates new group join requests. - CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error + CreateGroupRequest(ctx context.Context, requests []*model.GroupRequest) error // TakeGroupRequest retrieves a specific group join request. - TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationtb.GroupRequestModel, error) + TakeGroupRequest(ctx context.Context, groupID string, userID string) (*model.GroupRequest, error) // FindGroupRequests retrieves multiple group join requests. - FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error) + FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error) // PageGroupRequestUser paginates through group join requests made by a user. - PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) + PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) // CountTotal counts the total number of groups as of a certain date. CountTotal(ctx context.Context, before *time.Time) (count int64, err error) @@ -109,49 +111,46 @@ type GroupDatabase interface { func NewGroupDatabase( rdb redis.UniversalClient, localCache *config.LocalCache, - groupDB relationtb.GroupModelInterface, - groupMemberDB relationtb.GroupMemberModelInterface, - groupRequestDB relationtb.GroupRequestModelInterface, + groupDB database.Group, + groupMemberDB database.GroupMember, + groupRequestDB database.GroupRequest, ctxTx tx.Tx, groupHash cache.GroupHash, ) GroupDatabase { - rcOptions := rockscache.NewDefaultOptions() - rcOptions.StrongConsistency = true - rcOptions.RandomExpireAdjustment = 0.2 return &groupDatabase{ groupDB: groupDB, groupMemberDB: groupMemberDB, groupRequestDB: groupRequestDB, ctxTx: ctxTx, - cache: cache.NewGroupCacheRedis(rdb, localCache, groupDB, groupMemberDB, groupRequestDB, groupHash, rcOptions), + cache: redis2.NewGroupCacheRedis(rdb, localCache, groupDB, groupMemberDB, groupRequestDB, groupHash, redis2.GetRocksCacheOptions()), } } type groupDatabase struct { - groupDB relationtb.GroupModelInterface - groupMemberDB relationtb.GroupMemberModelInterface - groupRequestDB relationtb.GroupRequestModelInterface + groupDB database.Group + groupMemberDB database.GroupMember + groupRequestDB database.GroupRequest ctxTx tx.Tx cache cache.GroupCache } -func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) FindGroupMembers(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupMember, error) { return g.cache.GetGroupMembersInfo(ctx, groupID, userIDs) } -func (g *groupDatabase) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) ([]*model.GroupMember, error) { return g.cache.FindGroupMemberUser(ctx, groupIDs, userID) } -func (g *groupDatabase) FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) ([]*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) ([]*model.GroupMember, error) { return g.cache.GetGroupRolesLevelMemberInfo(ctx, groupID, roleLevels) } -func (g *groupDatabase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) FindGroupMemberAll(ctx context.Context, groupID string) ([]*model.GroupMember, error) { return g.cache.GetAllGroupMembersInfo(ctx, groupID) } -func (g *groupDatabase) FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*model.GroupMember, error) { return g.cache.GetGroupsOwner(ctx, groupIDs) } @@ -159,12 +158,12 @@ func (g *groupDatabase) GetGroupRoleLevelMemberIDs(ctx context.Context, groupID return g.cache.GetGroupRoleLevelMemberIDs(ctx, groupID, roleLevel) } -func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error { +func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*model.Group, groupMembers []*model.GroupMember) error { if len(groups)+len(groupMembers) == 0 { return nil } return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { - c := g.cache.NewCache() + c := g.cache.CloneGroupCache() if len(groups) > 0 { if err := g.groupDB.Create(ctx, groups); err != nil { return err @@ -191,7 +190,7 @@ func (g *groupDatabase) CreateGroup(ctx context.Context, groups []*relationtb.Gr DelGroupAllRoleLevel(groupMember.GroupID) } } - return c.ExecDel(ctx, true) + return c.ChainExecDel(ctx) }) } @@ -207,15 +206,15 @@ func (g *groupDatabase) FindGroupMemberNum(ctx context.Context, groupID string) return uint32(num), nil } -func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (*relationtb.GroupModel, error) { +func (g *groupDatabase) TakeGroup(ctx context.Context, groupID string) (*model.Group, error) { return g.cache.GetGroupInfo(ctx, groupID) } -func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) ([]*relationtb.GroupModel, error) { +func (g *groupDatabase) FindGroup(ctx context.Context, groupIDs []string) ([]*model.Group, error) { return g.cache.GetGroupsInfo(ctx, groupIDs) } -func (g *groupDatabase) SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) { +func (g *groupDatabase) SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*model.Group, error) { return g.groupDB.Search(ctx, keyword, pagination) } @@ -223,12 +222,12 @@ func (g *groupDatabase) UpdateGroup(ctx context.Context, groupID string, data ma if err := g.groupDB.UpdateMap(ctx, groupID, data); err != nil { return err } - return g.cache.DelGroupsInfo(groupID).ExecDel(ctx) + return g.cache.DelGroupsInfo(groupID).ChainExecDel(ctx) } func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, deleteMember bool) error { return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { - c := g.cache.NewCache() + c := g.cache.CloneGroupCache() if err := g.groupDB.UpdateStatus(ctx, groupID, constant.GroupStatusDismissed); err != nil { return err } @@ -247,15 +246,15 @@ func (g *groupDatabase) DismissGroup(ctx context.Context, groupID string, delete DelGroupAllRoleLevel(groupID). DelGroupMembersInfo(groupID, userIDs...) } - return c.DelGroupsInfo(groupID).ExecDel(ctx) + return c.DelGroupsInfo(groupID).ChainExecDel(ctx) }) } -func (g *groupDatabase) TakeGroupMember(ctx context.Context, groupID string, userID string) (*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) TakeGroupMember(ctx context.Context, groupID string, userID string) (*model.GroupMember, error) { return g.cache.GetGroupMemberInfo(ctx, groupID, userID) } -func (g *groupDatabase) TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) TakeGroupOwner(ctx context.Context, groupID string) (*model.GroupMember, error) { return g.cache.GetGroupOwner(ctx, groupID) } @@ -263,11 +262,11 @@ func (g *groupDatabase) FindUserManagedGroupID(ctx context.Context, userID strin return g.groupMemberDB.FindUserManagedGroupID(ctx, userID) } -func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) { +func (g *groupDatabase) PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) { return g.groupRequestDB.PageGroup(ctx, groupIDs, pagination) } -func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*model.GroupMember, err error) { groupIDs, err := g.cache.GetJoinedGroupIDs(ctx, userID) if err != nil { return 0, nil, err @@ -282,7 +281,7 @@ func (g *groupDatabase) PageGetJoinGroup(ctx context.Context, userID string, pag return int64(len(groupIDs)), totalGroupMembers, nil } -func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) { +func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*model.GroupMember, err error) { groupMemberIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID) if err != nil { return 0, nil, err @@ -298,26 +297,27 @@ func (g *groupDatabase) PageGetGroupMember(ctx context.Context, groupID string, return int64(len(groupMemberIDs)), members, nil } -func (g *groupDatabase) SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) { +func (g *groupDatabase) SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*model.GroupMember, 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 { +func (g *groupDatabase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *model.GroupMember) 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.Create(ctx, []*relationtb.GroupMemberModel{member}); err != nil { + c := g.cache.CloneGroupCache() + if err := g.groupMemberDB.Create(ctx, []*model.GroupMember{member}); err != nil { return err } - c := g.cache.DelGroupMembersHash(groupID). + c = c.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 { + if err := c.ChainExecDel(ctx); err != nil { return err } } @@ -329,16 +329,17 @@ func (g *groupDatabase) DeleteGroupMember(ctx context.Context, groupID string, u if err := g.groupMemberDB.Delete(ctx, groupID, userIDs); err != nil { return err } - return g.cache.DelGroupMembersHash(groupID). + c := g.cache.CloneGroupCache() + return c.DelGroupMembersHash(groupID). DelGroupMemberIDs(groupID). DelGroupsMemberNum(groupID). DelJoinedGroupID(userIDs...). DelGroupMembersInfo(groupID, userIDs...). DelGroupAllRoleLevel(groupID). - ExecDel(ctx) + ChainExecDel(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]*common.GroupSimpleUserID, error) { return g.cache.GetGroupMemberHashMap(ctx, groupIDs) } @@ -362,9 +363,10 @@ func (g *groupDatabase) TransferGroupOwner(ctx context.Context, groupID string, if err := g.groupMemberDB.UpdateRoleLevel(ctx, groupID, newOwnerUserID, constant.GroupOwner); err != nil { return err } - return g.cache.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID). + c := g.cache.CloneGroupCache() + return c.DelGroupMembersInfo(groupID, oldOwnerUserID, newOwnerUserID). DelGroupAllRoleLevel(groupID). - DelGroupMembersHash(groupID).ExecDel(ctx) + DelGroupMembersHash(groupID).ChainExecDel(ctx) }) } @@ -372,16 +374,17 @@ func (g *groupDatabase) UpdateGroupMember(ctx context.Context, groupID string, u if err := g.groupMemberDB.Update(ctx, groupID, userID, data); err != nil { return err } - c := g.cache.DelGroupMembersInfo(groupID, userID) + c := g.cache.CloneGroupCache() + c = c.DelGroupMembersInfo(groupID, userID) if g.groupMemberDB.IsUpdateRoleLevel(data) { c = c.DelGroupAllRoleLevel(groupID) } - return c.ExecDel(ctx) + return c.ChainExecDel(ctx) } -func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error { +func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*common.BatchUpdateGroupMember) error { return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { - c := g.cache.NewCache() + c := g.cache.CloneGroupCache() for _, item := range data { if err := g.groupMemberDB.Update(ctx, item.GroupID, item.UserID, item.Map); err != nil { return err @@ -391,11 +394,11 @@ func (g *groupDatabase) UpdateGroupMembers(ctx context.Context, data []*relation } c = c.DelGroupMembersInfo(item.GroupID, item.UserID).DelGroupMembersHash(item.GroupID) } - return c.ExecDel(ctx, true) + return c.ChainExecDel(ctx) }) } -func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error { +func (g *groupDatabase) CreateGroupRequest(ctx context.Context, requests []*model.GroupRequest) error { return g.ctxTx.Transaction(ctx, func(ctx context.Context) error { for _, request := range requests { if err := g.groupRequestDB.Delete(ctx, request.GroupID, request.UserID); err != nil { @@ -410,11 +413,11 @@ func (g *groupDatabase) TakeGroupRequest( ctx context.Context, groupID string, userID string, -) (*relationtb.GroupRequestModel, error) { +) (*model.GroupRequest, error) { return g.groupRequestDB.Take(ctx, groupID, userID) } -func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) { +func (g *groupDatabase) PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*model.GroupRequest, error) { return g.groupRequestDB.Page(ctx, userID, pagination) } @@ -426,7 +429,7 @@ 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) ([]*relationtb.GroupRequestModel, error) { +func (g *groupDatabase) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error) { return g.groupRequestDB.FindGroupRequests(ctx, groupID, userIDs) } @@ -434,9 +437,9 @@ func (g *groupDatabase) DeleteGroupMemberHash(ctx context.Context, groupIDs []st if len(groupIDs) == 0 { return nil } - c := g.cache.NewCache() + c := g.cache.CloneGroupCache() for _, groupID := range groupIDs { c = c.DelGroupMembersHash(groupID) } - return c.ExecDel(ctx) + return c.ChainExecDel(ctx) } diff --git a/pkg/common/db/controller/msg.go b/pkg/common/storage/controller/msg.go similarity index 93% rename from pkg/common/db/controller/msg.go rename to pkg/common/storage/controller/msg.go index c0a013c17..ce107e923 100644 --- a/pkg/common/db/controller/msg.go +++ b/pkg/common/storage/controller/msg.go @@ -18,14 +18,15 @@ import ( "context" "encoding/json" "errors" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "strings" "time" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/common/convert" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/protocol/constant" pbmsg "github.com/openimsdk/protocol/msg" "github.com/openimsdk/protocol/sdkws" @@ -48,7 +49,7 @@ type CommonMsgDatabase interface { // BatchInsertChat2DB inserts a batch of messages into the database for a specific conversation. BatchInsertChat2DB(ctx context.Context, conversationID string, msgs []*sdkws.MsgData, currentMaxSeq int64) error // RevokeMsg revokes a message in a conversation. - RevokeMsg(ctx context.Context, conversationID string, seq int64, revoke *relation.RevokeModel) error + RevokeMsg(ctx context.Context, conversationID string, seq int64, revoke *model.RevokeModel) error // MarkSingleChatMsgsAsRead marks messages as read for a single chat by sequence numbers. MarkSingleChatMsgsAsRead(ctx context.Context, userID string, conversationID string, seqs []int64) error // DeleteMessagesFromCache deletes message caches from Redis by sequence numbers. @@ -101,16 +102,16 @@ type CommonMsgDatabase interface { MsgToPushMQ(ctx context.Context, key, conversarionID string, msg2mq *sdkws.MsgData) (int32, int64, error) MsgToMongoMQ(ctx context.Context, key, conversarionID string, msgs []*sdkws.MsgData, lastSeq int64) error - RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*relation.UserCount, dateCount map[string]int64, err error) - RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*relation.GroupCount, dateCount map[string]int64, err error) + RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*model.UserCount, dateCount map[string]int64, err error) + RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*model.GroupCount, dateCount map[string]int64, err error) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) // clear msg - GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*relation.MsgDocModel, error) - DeleteDocMsgBefore(ctx context.Context, ts int64, doc *relation.MsgDocModel) ([]int, error) + GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) + DeleteDocMsgBefore(ctx context.Context, ts int64, doc *model.MsgDocModel) ([]int, error) } -func NewCommonMsgDatabase(msgDocModel relation.MsgDocModelInterface, msg cache.MsgCache, seq cache.SeqCache, kafkaConf *config.Kafka) (CommonMsgDatabase, error) { +func NewCommonMsgDatabase(msgDocModel database.Msg, msg cache.MsgCache, seq cache.SeqCache, kafkaConf *config.Kafka) (CommonMsgDatabase, error) { conf, err := kafka.BuildProducerConfig(*kafkaConf.Build()) if err != nil { return nil, err @@ -138,7 +139,7 @@ func NewCommonMsgDatabase(msgDocModel relation.MsgDocModelInterface, msg cache.M } //func InitCommonMsgDatabase(rdb redis.UniversalClient, database *mongo.Database, config *tools.CronTaskConfig) (CommonMsgDatabase, error) { -// msgDocModel, err := mgo.NewMsgMongo(database) +// msgDocModel, err := database.NewMsgMongo(database) // if err != nil { // return nil, err // } @@ -149,8 +150,8 @@ func NewCommonMsgDatabase(msgDocModel relation.MsgDocModelInterface, msg cache.M //} type commonMsgDatabase struct { - msgDocDatabase relation.MsgDocModelInterface - msgTable relation.MsgDocModel + msgDocDatabase database.Msg + msgTable model.MsgDocModel msg cache.MsgCache seq cache.SeqCache producer *kafka.Producer @@ -199,13 +200,13 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI var ok bool switch key { case updateKeyMsg: - var msg *relation.MsgDataModel - msg, ok = field.(*relation.MsgDataModel) + var msg *model.MsgDataModel + msg, ok = field.(*model.MsgDataModel) if msg != nil && msg.Seq != firstSeq+int64(i) { return errs.ErrInternalServer.WrapMsg("seq is invalid") } case updateKeyRevoke: - _, ok = field.(*relation.RevokeModel) + _, ok = field.(*model.RevokeModel) default: return errs.ErrInternalServer.WrapMsg("key is invalid") } @@ -245,9 +246,9 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI continue // The current data has been updated, skip the current data } } - doc := relation.MsgDocModel{ + doc := model.MsgDocModel{ DocID: db.msgTable.GetDocID(conversationID, seq), - Msg: make([]*relation.MsgInfoModel, num), + Msg: make([]*model.MsgInfoModel, num), } var insert int // Inserted data number for j := i; j < len(fields); j++ { @@ -258,21 +259,21 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI insert++ switch key { case updateKeyMsg: - doc.Msg[db.msgTable.GetMsgIndex(seq)] = &relation.MsgInfoModel{ - Msg: fields[j].(*relation.MsgDataModel), + doc.Msg[db.msgTable.GetMsgIndex(seq)] = &model.MsgInfoModel{ + Msg: fields[j].(*model.MsgDataModel), } case updateKeyRevoke: - doc.Msg[db.msgTable.GetMsgIndex(seq)] = &relation.MsgInfoModel{ - Revoke: fields[j].(*relation.RevokeModel), + doc.Msg[db.msgTable.GetMsgIndex(seq)] = &model.MsgInfoModel{ + Revoke: fields[j].(*model.RevokeModel), } } } - for i, model := range doc.Msg { - if model == nil { - model = &relation.MsgInfoModel{} - doc.Msg[i] = model + for i, msgInfo := range doc.Msg { + if msgInfo == nil { + msgInfo = &model.MsgInfoModel{} + doc.Msg[i] = msgInfo } - if model.DelList == nil { + if msgInfo.DelList == nil { doc.Msg[i].DelList = []string{} } } @@ -299,9 +300,9 @@ func (db *commonMsgDatabase) BatchInsertChat2DB(ctx context.Context, conversatio if msg == nil { continue } - var offlinePushModel *relation.OfflinePushModel + var offlinePushModel *model.OfflinePushModel if msg.OfflinePushInfo != nil { - offlinePushModel = &relation.OfflinePushModel{ + offlinePushModel = &model.OfflinePushModel{ Title: msg.OfflinePushInfo.Title, Desc: msg.OfflinePushInfo.Desc, Ex: msg.OfflinePushInfo.Ex, @@ -309,7 +310,7 @@ func (db *commonMsgDatabase) BatchInsertChat2DB(ctx context.Context, conversatio IOSBadgeCount: msg.OfflinePushInfo.IOSBadgeCount, } } - msgs[i] = &relation.MsgDataModel{ + msgs[i] = &model.MsgDataModel{ SendID: msg.SendID, RecvID: msg.RecvID, GroupID: msg.GroupID, @@ -336,7 +337,7 @@ func (db *commonMsgDatabase) BatchInsertChat2DB(ctx context.Context, conversatio return db.BatchInsertBlock(ctx, conversationID, msgs, updateKeyMsg, msgList[0].Seq) } -func (db *commonMsgDatabase) RevokeMsg(ctx context.Context, conversationID string, seq int64, revoke *relation.RevokeModel) error { +func (db *commonMsgDatabase) RevokeMsg(ctx context.Context, conversationID string, seq int64, revoke *model.RevokeModel) error { return db.BatchInsertBlock(ctx, conversationID, []any{revoke}, updateKeyRevoke, seq) } @@ -366,7 +367,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) { currentMaxSeq, err := db.seq.GetMaxSeq(ctx, conversationID) if err != nil && errs.Unwrap(err) != redis.Nil { - log.ZError(ctx, "db.seq.GetMaxSeq", err) + log.ZError(ctx, "storage.seq.GetMaxSeq", err) return 0, false, err } lenList := len(msgs) @@ -397,7 +398,7 @@ func (db *commonMsgDatabase) BatchInsertChat2Cache(ctx context.Context, conversa err = db.seq.SetMaxSeq(ctx, conversationID, currentMaxSeq) if err != nil { - log.ZError(ctx, "db.seq.SetMaxSeq error", err, "conversationID", conversationID) + log.ZError(ctx, "storage.seq.SetMaxSeq error", err, "conversationID", conversationID) prommetrics.SeqSetFailedCounter.Inc() } @@ -423,7 +424,7 @@ func (db *commonMsgDatabase) getMsgBySeqs(ctx context.Context, userID, conversat return totalMsgs, nil } -func (db *commonMsgDatabase) handlerDBMsg(ctx context.Context, cache map[int64][]*relation.MsgInfoModel, userID, conversationID string, msg *relation.MsgInfoModel) { +func (db *commonMsgDatabase) handlerDBMsg(ctx context.Context, cache map[int64][]*model.MsgInfoModel, userID, conversationID string, msg *model.MsgInfoModel) { if msg.IsRead { msg.Msg.IsRead = true } @@ -445,7 +446,7 @@ func (db *commonMsgDatabase) handlerDBMsg(ctx context.Context, cache map[int64][ if quoteMsg.QuoteMessage == nil || quoteMsg.QuoteMessage.ContentType == constant.MsgRevokeNotification { return } - var msgs []*relation.MsgInfoModel + var msgs []*model.MsgInfoModel if v, ok := cache[quoteMsg.QuoteMessage.Seq]; ok { msgs = v } else { @@ -479,12 +480,12 @@ func (db *commonMsgDatabase) handlerDBMsg(ctx context.Context, cache map[int64][ } } -func (db *commonMsgDatabase) findMsgInfoBySeq(ctx context.Context, userID, docID string, conversationID string, seqs []int64) (totalMsgs []*relation.MsgInfoModel, err error) { +func (db *commonMsgDatabase) findMsgInfoBySeq(ctx context.Context, userID, docID string, conversationID string, seqs []int64) (totalMsgs []*model.MsgInfoModel, err error) { msgs, err := db.msgDocDatabase.GetMsgBySeqIndexIn1Doc(ctx, userID, docID, seqs) if err != nil { return nil, err } - tempCache := make(map[int64][]*relation.MsgInfoModel) + tempCache := make(map[int64][]*model.MsgInfoModel) for _, msg := range msgs { db.handlerDBMsg(ctx, tempCache, userID, conversationID, msg) } @@ -636,7 +637,7 @@ func (db *commonMsgDatabase) GetMsgBySeqsRange(ctx context.Context, userID strin if len(failedSeqs) != 0 { log.ZDebug(ctx, "msgs not exist in redis", "seqs", failedSeqs) } - // get from cache or db + // get from cache or storage if len(failedSeqs) > 0 { mongoMsgs, err := db.getMsgBySeqsRange(ctx, userID, conversationID, failedSeqs, begin, end) @@ -678,7 +679,7 @@ func (db *commonMsgDatabase) GetMsgBySeqs(ctx context.Context, userID string, co log.ZError(ctx, "get message from redis exception", err, "failedSeqs", failedSeqs, "conversationID", conversationID) } } - log.ZDebug(ctx, "db.seq.GetMessagesBySeq", "userID", userID, "conversationID", conversationID, "seqs", + log.ZDebug(ctx, "storage.seq.GetMessagesBySeq", "userID", userID, "conversationID", conversationID, "seqs", seqs, "len(successMsgs)", len(successMsgs), "failedSeqs", failedSeqs) if len(failedSeqs) > 0 { @@ -720,7 +721,7 @@ func (db *commonMsgDatabase) UserMsgsDestruct(ctx context.Context, userID string msgDocModel, err := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1) if err != nil || msgDocModel.DocID == "" { if err != nil { - if err == relation.ErrMsgListNotExist { + if err == model.ErrMsgListNotExist { log.ZDebug(ctx, "not doc find", "conversationID", conversationID, "userID", userID, "index", index) } else { log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err, "conversationID", conversationID, "index", index) @@ -787,7 +788,7 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio msgDocModel, err := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1) if err != nil || msgDocModel.DocID == "" { if err != nil { - if err == relation.ErrMsgListNotExist { + if err == model.ErrMsgListNotExist { log.ZDebug(ctx, "deleteMsgRecursion ErrMsgListNotExist", "conversationID", conversationID, "index:", index) } else { log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err, "conversationID", conversationID, "index", index) @@ -1005,7 +1006,7 @@ func (db *commonMsgDatabase) RangeUserSendCount( ase bool, pageNumber int32, showNumber int32, -) (msgCount int64, userCount int64, users []*relation.UserCount, dateCount map[string]int64, err error) { +) (msgCount int64, userCount int64, users []*model.UserCount, dateCount map[string]int64, err error) { return db.msgDocDatabase.RangeUserSendCount(ctx, start, end, group, ase, pageNumber, showNumber) } @@ -1016,7 +1017,7 @@ func (db *commonMsgDatabase) RangeGroupSendCount( ase bool, pageNumber int32, showNumber int32, -) (msgCount int64, userCount int64, groups []*relation.GroupCount, dateCount map[string]int64, err error) { +) (msgCount int64, userCount int64, groups []*model.GroupCount, dateCount map[string]int64, err error) { return db.msgDocDatabase.RangeGroupSendCount(ctx, start, end, ase, pageNumber, showNumber) } @@ -1054,11 +1055,11 @@ func (db *commonMsgDatabase) ConvertMsgsDocLen(ctx context.Context, conversation db.msgDocDatabase.ConvertMsgsDocLen(ctx, conversationIDs) } -func (db *commonMsgDatabase) GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*relation.MsgDocModel, error) { +func (db *commonMsgDatabase) GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) { return db.msgDocDatabase.GetBeforeMsg(ctx, ts, limit) } -func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, doc *relation.MsgDocModel) ([]int, error) { +func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, doc *model.MsgDocModel) ([]int, error) { var notNull int index := make([]int, 0, len(doc.Msg)) for i, message := range doc.Msg { @@ -1084,14 +1085,14 @@ func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, d } } -//func (db *commonMsgDatabase) ClearMsg(ctx context.Context, ts int64) (err error) { +//func (storage *commonMsgDatabase) ClearMsg(ctx context.Context, ts int64) (err error) { // var ( // docNum int // msgNum int // start = time.Now() // ) // for { -// msgs, err := db.msgDocDatabase.GetBeforeMsg(ctx, ts, 100) +// msgs, err := storage.msgDocDatabase.GetBeforeMsg(ctx, ts, 100) // if err != nil { // return err // } @@ -1099,7 +1100,7 @@ func (db *commonMsgDatabase) DeleteDocMsgBefore(ctx context.Context, ts int64, d // return nil // } // for _, msg := range msgs { -// num, err := db.deleteOneMsg(ctx, ts, msg) +// num, err := storage.deleteOneMsg(ctx, ts, msg) // if err != nil { // return err // } diff --git a/pkg/common/db/controller/push.go b/pkg/common/storage/controller/push.go similarity index 94% rename from pkg/common/db/controller/push.go rename to pkg/common/storage/controller/push.go index 390d70b7b..199a0ba67 100644 --- a/pkg/common/db/controller/push.go +++ b/pkg/common/storage/controller/push.go @@ -17,7 +17,7 @@ package controller import ( "context" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" ) type PushDatabase interface { diff --git a/pkg/common/db/controller/s3.go b/pkg/common/storage/controller/s3.go similarity index 84% rename from pkg/common/db/controller/s3.go rename to pkg/common/storage/controller/s3.go index eae47c421..b0ad61203 100644 --- a/pkg/common/db/controller/s3.go +++ b/pkg/common/storage/controller/s3.go @@ -16,11 +16,13 @@ package controller import ( "context" + redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "path/filepath" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/tools/s3" "github.com/openimsdk/tools/s3/cont" "github.com/redis/go-redis/v9" @@ -33,15 +35,15 @@ type S3Database interface { InitiateMultipartUpload(ctx context.Context, hash string, size int64, expire time.Duration, maxParts int) (*cont.InitiateUploadResult, error) CompleteMultipartUpload(ctx context.Context, uploadID string, parts []string) (*cont.UploadResult, error) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) - SetObject(ctx context.Context, info *relation.ObjectModel) error + SetObject(ctx context.Context, info *model.Object) error StatObject(ctx context.Context, name string) (*s3.ObjectInfo, error) FormData(ctx context.Context, name string, size int64, contentType string, duration time.Duration) (*s3.FormData, error) } -func NewS3Database(rdb redis.UniversalClient, s3 s3.Interface, obj relation.ObjectInfoModelInterface) S3Database { +func NewS3Database(rdb redis.UniversalClient, s3 s3.Interface, obj database.ObjectInfo) S3Database { return &s3Database{ - s3: cont.New(cache.NewS3Cache(rdb, s3), s3), - cache: cache.NewObjectCacheRedis(rdb, obj), + s3: cont.New(redis2.NewS3Cache(rdb, s3), s3), + cache: redis2.NewObjectCacheRedis(rdb, obj), db: obj, } } @@ -49,7 +51,7 @@ func NewS3Database(rdb redis.UniversalClient, s3 s3.Interface, obj relation.Obje type s3Database struct { s3 *cont.Controller cache cache.ObjectCache - db relation.ObjectInfoModelInterface + db database.ObjectInfo } func (s *s3Database) PartSize(ctx context.Context, size int64) (int64, error) { @@ -72,12 +74,12 @@ func (s *s3Database) CompleteMultipartUpload(ctx context.Context, uploadID strin return s.s3.CompleteUpload(ctx, uploadID, parts) } -func (s *s3Database) SetObject(ctx context.Context, info *relation.ObjectModel) error { +func (s *s3Database) SetObject(ctx context.Context, info *model.Object) error { info.Engine = s.s3.Engine() if err := s.db.SetObject(ctx, info); err != nil { return err } - return s.cache.DelObjectName(info.Engine, info.Name).ExecDel(ctx) + return s.cache.DelObjectName(info.Engine, info.Name).ChainExecDel(ctx) } func (s *s3Database) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (time.Time, string, error) { diff --git a/pkg/common/db/controller/third.go b/pkg/common/storage/controller/third.go similarity index 80% rename from pkg/common/db/controller/third.go rename to pkg/common/storage/controller/third.go index be618843f..344501466 100644 --- a/pkg/common/db/controller/third.go +++ b/pkg/common/storage/controller/third.go @@ -16,10 +16,11 @@ package controller import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" "github.com/openimsdk/tools/db/pagination" ) @@ -27,15 +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.LogModel) error + UploadLogs(ctx context.Context, logs []*model.Log) error DeleteLogs(ctx context.Context, logID []string, userID string) error - SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) - GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*relation.LogModel, error) + SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*model.Log, error) + GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*model.Log, error) } type thirdDatabase struct { cache cache.ThirdCache - logdb relation.LogInterface + logdb database.Log } // DeleteLogs implements ThirdDatabase. @@ -44,21 +45,21 @@ 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.LogModel, error) { +func (t *thirdDatabase) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*model.Log, error) { return t.logdb.Get(ctx, LogIDs, userID) } // SearchLogs implements ThirdDatabase. -func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) { +func (t *thirdDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*model.Log, error) { return t.logdb.Search(ctx, keyword, start, end, pagination) } // UploadLogs implements ThirdDatabase. -func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*relation.LogModel) error { +func (t *thirdDatabase) UploadLogs(ctx context.Context, logs []*model.Log) error { return t.logdb.Create(ctx, logs) } -func NewThirdDatabase(cache cache.ThirdCache, logdb relation.LogInterface) ThirdDatabase { +func NewThirdDatabase(cache cache.ThirdCache, logdb database.Log) ThirdDatabase { return &thirdDatabase{cache: cache, logdb: logdb} } diff --git a/pkg/common/db/controller/user.go b/pkg/common/storage/controller/user.go similarity index 82% rename from pkg/common/db/controller/user.go rename to pkg/common/storage/controller/user.go index b2aba41fa..09dc2db22 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/storage/controller/user.go @@ -16,6 +16,8 @@ package controller import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/db/tx" "github.com/openimsdk/tools/utils/datautil" @@ -24,37 +26,36 @@ import ( "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/errs" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/cache" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache" ) type UserDatabase interface { // FindWithError Get the information of the specified user. If the userID is not found, it will also return an error - FindWithError(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) + FindWithError(ctx context.Context, userIDs []string) (users []*model.User, err error) // Find Get the information of the specified user If the userID is not found, no error will be returned - Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) + Find(ctx context.Context, userIDs []string) (users []*model.User, err error) // Find userInfo By Nickname - FindByNickname(ctx context.Context, nickname string) (users []*relation.UserModel, err error) + FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error) // Find notificationAccounts - FindNotification(ctx context.Context, level int64) (users []*relation.UserModel, err error) - // 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) + FindNotification(ctx context.Context, level int64) (users []*model.User, err error) + // Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage + Create(ctx context.Context, users []*model.User) (err error) // UpdateByMap update (zero value) external guarantee userID exists UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) // FindUser - PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) + PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error) // FindUser with keyword - PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, nickName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) + PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID string, nickName string, pagination pagination.Pagination) (count int64, users []*model.User, err error) // Page If not found, no error is returned - Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) + Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, 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, pagination pagination.Pagination) (int64, []string, error) // Get user by userID - GetUserByID(ctx context.Context, userID string) (user *relation.UserModel, err 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) + GetUserByID(ctx context.Context, userID string) (user *model.User, err error) + // InitOnce Inside the function, first query whether it exists in the storage, if it exists, do nothing; if it does not exist, insert it + InitOnce(ctx context.Context, users []*model.User) (err error) // CountTotal Get the total number of users CountTotal(ctx context.Context, before *time.Time) (int64, error) // CountRangeEverydayTotal Get the user increment in the range @@ -82,18 +83,18 @@ type UserDatabase interface { type userDatabase struct { tx tx.Tx - userDB relation.UserModelInterface + userDB database.User cache cache.UserCache - mongoDB relation.SubscribeUserModelInterface + mongoDB database.SubscribeUser } -func NewUserDatabase(userDB relation.UserModelInterface, cache cache.UserCache, tx tx.Tx, mongoDB relation.SubscribeUserModelInterface) UserDatabase { +func NewUserDatabase(userDB database.User, cache cache.UserCache, tx tx.Tx, mongoDB database.SubscribeUser) UserDatabase { return &userDatabase{userDB: userDB, cache: cache, tx: tx, mongoDB: mongoDB} } -func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel) error { +func (u *userDatabase) InitOnce(ctx context.Context, users []*model.User) error { // Extract user IDs from the given user models. - userIDs := datautil.Slice(users, func(e *relation.UserModel) string { + userIDs := datautil.Slice(users, func(e *model.User) string { return e.UserID }) @@ -104,7 +105,7 @@ func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel } // Determine which users are missing from the database. - missingUsers := datautil.SliceAnySub(users, existingUsers, func(e *relation.UserModel) string { + missingUsers := datautil.SliceAnySub(users, existingUsers, func(e *model.User) string { return e.UserID }) @@ -119,7 +120,7 @@ func (u *userDatabase) InitOnce(ctx context.Context, users []*relation.UserModel } // FindWithError Get the information of the specified user and return an error if the userID is not found. -func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { +func (u *userDatabase) FindWithError(ctx context.Context, userIDs []string) (users []*model.User, err error) { users, err = u.cache.GetUsersInfo(ctx, userIDs) if err != nil { return @@ -131,27 +132,27 @@ 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) { +func (u *userDatabase) Find(ctx context.Context, userIDs []string) (users []*model.User, err error) { return u.cache.GetUsersInfo(ctx, userIDs) } -func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (users []*relation.UserModel, err error) { +func (u *userDatabase) FindByNickname(ctx context.Context, nickname string) (users []*model.User, err error) { return u.userDB.TakeByNickname(ctx, nickname) } -func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users []*relation.UserModel, err error) { +func (u *userDatabase) FindNotification(ctx context.Context, level int64) (users []*model.User, err error) { return u.userDB.TakeNotification(ctx, level) } -// 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) { +// Create Insert multiple external guarantees that the userID is not repeated and does not exist in the storage. +func (u *userDatabase) Create(ctx context.Context, users []*model.User) (err error) { return u.tx.Transaction(ctx, func(ctx context.Context) error { if err = u.userDB.Create(ctx, users); err != nil { return err } - return u.cache.DelUsersInfo(datautil.Slice(users, func(e *relation.UserModel) string { + return u.cache.DelUsersInfo(datautil.Slice(users, func(e *model.User) string { return e.UserID - })...).ExecDel(ctx) + })...).ChainExecDel(ctx) }) } @@ -161,20 +162,20 @@ func (u *userDatabase) UpdateByMap(ctx context.Context, userID string, args map[ if err := u.userDB.UpdateByMap(ctx, userID, args); err != nil { return err } - return u.cache.DelUsersInfo(userID).ExecDel(ctx) + return u.cache.DelUsersInfo(userID).ChainExecDel(ctx) }) } // Page Gets, returns no error if not found. -func (u *userDatabase) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { +func (u *userDatabase) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error) { return u.userDB.Page(ctx, pagination) } -func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { +func (u *userDatabase) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error) { return u.userDB.PageFindUser(ctx, level1, level2, pagination) } -func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { +func (u *userDatabase) PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*model.User, err error) { return u.userDB.PageFindUserWithKeyword(ctx, level1, level2, userID, nickName, pagination) } @@ -195,7 +196,7 @@ func (u *userDatabase) GetAllUserID(ctx context.Context, pagination pagination.P return u.userDB.GetAllUserID(ctx, pagination) } -func (u *userDatabase) GetUserByID(ctx context.Context, userID string) (user *relation.UserModel, err error) { +func (u *userDatabase) GetUserByID(ctx context.Context, userID string) (user *model.User, err error) { return u.userDB.Take(ctx, userID) } diff --git a/pkg/common/db/table/relation/black.go b/pkg/common/storage/database/black.go similarity index 51% rename from pkg/common/db/table/relation/black.go rename to pkg/common/storage/database/black.go index f5d1cb236..b53fdd14d 100644 --- a/pkg/common/db/table/relation/black.go +++ b/pkg/common/storage/database/black.go @@ -12,32 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" ) -type BlackModel struct { - OwnerUserID string `bson:"owner_user_id"` - BlockUserID string `bson:"block_user_id"` - CreateTime time.Time `bson:"create_time"` - AddSource int32 `bson:"add_source"` - OperatorUserID string `bson:"operator_user_id"` - Ex string `bson:"ex"` -} - -type BlackModelInterface interface { - Create(ctx context.Context, blacks []*BlackModel) (err error) - Delete(ctx context.Context, blacks []*BlackModel) (err error) - // UpdateByMap(ctx context.Context, ownerUserID, blockUserID string, args map[string]any) (err error) - // Update(ctx context.Context, blacks []*BlackModel) (err error) - Find(ctx context.Context, blacks []*BlackModel) (blackList []*BlackModel, err error) - Take(ctx context.Context, ownerUserID, blockUserID string) (black *BlackModel, err error) - FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*BlackModel, err error) - FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*BlackModel, err error) +type Black interface { + Create(ctx context.Context, blacks []*model.Black) (err error) + Delete(ctx context.Context, blacks []*model.Black) (err error) + Find(ctx context.Context, blacks []*model.Black) (blackList []*model.Black, err error) + Take(ctx context.Context, ownerUserID, blockUserID string) (black *model.Black, err error) + FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*model.Black, err error) + FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*model.Black, err error) FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) } diff --git a/pkg/common/db/table/relation/conversation.go b/pkg/common/storage/database/conversation.go similarity index 56% rename from pkg/common/db/table/relation/conversation.go rename to pkg/common/storage/database/conversation.go index 4990c96c6..46aa02d98 100644 --- a/pkg/common/db/table/relation/conversation.go +++ b/pkg/common/storage/database/conversation.go @@ -12,53 +12,31 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" ) -type ConversationModel struct { - OwnerUserID string `bson:"owner_user_id"` - ConversationID string `bson:"conversation_id"` - ConversationType int32 `bson:"conversation_type"` - UserID string `bson:"user_id"` - GroupID string `bson:"group_id"` - RecvMsgOpt int32 `bson:"recv_msg_opt"` - IsPinned bool `bson:"is_pinned"` - IsPrivateChat bool `bson:"is_private_chat"` - BurnDuration int32 `bson:"burn_duration"` - GroupAtType int32 `bson:"group_at_type"` - AttachedInfo string `bson:"attached_info"` - Ex string `bson:"ex"` - MaxSeq int64 `bson:"max_seq"` - MinSeq int64 `bson:"min_seq"` - CreateTime time.Time `bson:"create_time"` - IsMsgDestruct bool `bson:"is_msg_destruct"` - MsgDestructTime int64 `bson:"msg_destruct_time"` - LatestMsgDestructTime time.Time `bson:"latest_msg_destruct_time"` -} - -type ConversationModelInterface interface { - Create(ctx context.Context, conversations []*ConversationModel) (err error) +type Conversation interface { + Create(ctx context.Context, conversations []*model.Conversation) (err error) Delete(ctx context.Context, groupIDs []string) (err error) UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]any) (rows int64, err error) - Update(ctx context.Context, conversation *ConversationModel) (err error) - Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*ConversationModel, err error) + Update(ctx context.Context, conversation *model.Conversation) (err error) + Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*model.Conversation, err error) FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error) FindUserIDAllConversationID(ctx context.Context, userID string) ([]string, error) - Take(ctx context.Context, userID, conversationID string) (conversation *ConversationModel, err error) + Take(ctx context.Context, userID, conversationID string) (conversation *model.Conversation, err error) FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error) - FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*ConversationModel, err error) + FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*model.Conversation, err error) FindRecvMsgUserIDs(ctx context.Context, conversationID string, recvOpts []int) ([]string, error) GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error) GetAllConversationIDs(ctx context.Context) ([]string, error) GetAllConversationIDsNumber(ctx context.Context) (int64, error) PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) - GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*ConversationModel, error) - GetConversationIDsNeedDestruct(ctx context.Context) ([]*ConversationModel, error) + GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*model.Conversation, error) + GetConversationIDsNeedDestruct(ctx context.Context) ([]*model.Conversation, error) GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) } diff --git a/pkg/common/storage/database/doc.go b/pkg/common/storage/database/doc.go new file mode 100644 index 000000000..4a691442e --- /dev/null +++ b/pkg/common/storage/database/doc.go @@ -0,0 +1,15 @@ +// Copyright © 2024 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 database // import "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model/relation" diff --git a/pkg/common/db/table/relation/friend.go b/pkg/common/storage/database/friend.go similarity index 70% rename from pkg/common/db/table/relation/friend.go rename to pkg/common/storage/database/friend.go index 4c84e773d..33d9c17bc 100644 --- a/pkg/common/db/table/relation/friend.go +++ b/pkg/common/storage/database/friend.go @@ -12,31 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" ) -// FriendModel represents the data structure for a friend relationship in MongoDB. -type FriendModel struct { - OwnerUserID string `bson:"owner_user_id"` - FriendUserID string `bson:"friend_user_id"` - Remark string `bson:"remark"` - CreateTime time.Time `bson:"create_time"` - AddSource int32 `bson:"add_source"` - OperatorUserID string `bson:"operator_user_id"` - Ex string `bson:"ex"` - IsPinned bool `bson:"is_pinned"` -} - -// FriendModelInterface defines the operations for managing friends in MongoDB. -type FriendModelInterface interface { +// Friend defines the operations for managing friends in MongoDB. +type Friend interface { // Create inserts multiple friend records. - Create(ctx context.Context, friends []*FriendModel) (err error) + Create(ctx context.Context, friends []*model.Friend) (err error) // Delete removes specified friends of the owner user. Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) // UpdateByMap updates specific fields of a friend document using a map. @@ -44,17 +31,17 @@ type FriendModelInterface interface { // UpdateRemark modify remarks. UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) // Take retrieves a single friend document. Returns an error if not found. - Take(ctx context.Context, ownerUserID, friendUserID string) (friend *FriendModel, err error) + Take(ctx context.Context, ownerUserID, friendUserID string) (friend *model.Friend, err error) // FindUserState finds the friendship status between two users. - FindUserState(ctx context.Context, userID1, userID2 string) (friends []*FriendModel, err error) + FindUserState(ctx context.Context, userID1, userID2 string) (friends []*model.Friend, err error) // FindFriends retrieves a list of friends for a given owner. Missing friends do not cause an error. - FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*FriendModel, err error) + FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*model.Friend, err error) // FindReversalFriends finds users who have added the specified user as a friend. - FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) (friends []*FriendModel, err error) + FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) (friends []*model.Friend, err error) // FindOwnerFriends retrieves a paginated list of friends for a given owner. - FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, err error) + FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error) // FindInWhoseFriends finds users who have added the specified user as a friend, with pagination. - FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*FriendModel, err error) + FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*model.Friend, err error) // FindFriendUserIDs retrieves a list of friend user IDs for a given owner. FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) // UpdateFriends update friends' fields diff --git a/pkg/common/db/table/relation/friend_request.go b/pkg/common/storage/database/friend_request.go similarity index 60% rename from pkg/common/db/table/relation/friend_request.go rename to pkg/common/storage/database/friend_request.go index d59e3bb0b..f163b4831 100644 --- a/pkg/common/db/table/relation/friend_request.go +++ b/pkg/common/storage/database/friend_request.go @@ -12,42 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" ) -type FriendRequestModel struct { - FromUserID string `bson:"from_user_id"` - ToUserID string `bson:"to_user_id"` - HandleResult int32 `bson:"handle_result"` - ReqMsg string `bson:"req_msg"` - CreateTime time.Time `bson:"create_time"` - HandlerUserID string `bson:"handler_user_id"` - HandleMsg string `bson:"handle_msg"` - HandleTime time.Time `bson:"handle_time"` - Ex string `bson:"ex"` -} - -type FriendRequestModelInterface interface { +type FriendRequest interface { // Insert multiple records - Create(ctx context.Context, friendRequests []*FriendRequestModel) (err error) + Create(ctx context.Context, friendRequests []*model.FriendRequest) (err error) // Delete record Delete(ctx context.Context, fromUserID, toUserID string) (err error) // Update with zero values UpdateByMap(ctx context.Context, formUserID string, toUserID string, args map[string]any) (err error) // Update multiple records (non-zero values) - Update(ctx context.Context, friendRequest *FriendRequestModel) (err error) + Update(ctx context.Context, friendRequest *model.FriendRequest) (err error) // Get friend requests sent to a specific user, no error returned if not found - Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) - Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error) + Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) + Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) // Get list of friend requests received by toUserID - FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*FriendRequestModel, err error) + FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) // Get list of friend requests sent by fromUserID - FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*FriendRequestModel, err error) - FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*FriendRequestModel, err error) + FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) + FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) } diff --git a/pkg/common/storage/database/group.go b/pkg/common/storage/database/group.go new file mode 100644 index 000000000..712db09d2 --- /dev/null +++ b/pkg/common/storage/database/group.go @@ -0,0 +1,35 @@ +// 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 database + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/tools/db/pagination" + "time" +) + +type Group interface { + Create(ctx context.Context, groups []*model.Group) (err error) + UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) + UpdateStatus(ctx context.Context, groupID string, status int32) (err error) + Find(ctx context.Context, groupIDs []string) (groups []*model.Group, err error) + Take(ctx context.Context, groupID string) (group *model.Group, err error) + Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*model.Group, err error) + // Get Group total quantity + CountTotal(ctx context.Context, before *time.Time) (count int64, err error) + // Get Group total quantity every day + CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) +} diff --git a/pkg/common/db/table/relation/group_member.go b/pkg/common/storage/database/group_member.go similarity index 56% rename from pkg/common/db/table/relation/group_member.go rename to pkg/common/storage/database/group_member.go index 37f1cfc03..f57f2c317 100644 --- a/pkg/common/db/table/relation/group_member.go +++ b/pkg/common/storage/database/group_member.go @@ -12,46 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" ) -type GroupMemberModel struct { - GroupID string `bson:"group_id"` - UserID string `bson:"user_id"` - Nickname string `bson:"nickname"` - FaceURL string `bson:"face_url"` - RoleLevel int32 `bson:"role_level"` - JoinTime time.Time `bson:"join_time"` - JoinSource int32 `bson:"join_source"` - InviterUserID string `bson:"inviter_user_id"` - OperatorUserID string `bson:"operator_user_id"` - MuteEndTime time.Time `bson:"mute_end_time"` - Ex string `bson:"ex"` -} - -type GroupMemberModelInterface interface { - // NewTx(tx any) GroupMemberModelInterface - Create(ctx context.Context, groupMembers []*GroupMemberModel) (err error) +type GroupMember interface { + Create(ctx context.Context, groupMembers []*model.GroupMember) (err error) Delete(ctx context.Context, groupID string, userIDs []string) (err error) - // DeleteGroup(ctx context.Context, groupIDs []string) (err error) Update(ctx context.Context, groupID string, userID string, data map[string]any) (err error) UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32) error FindMemberUserID(ctx context.Context, groupID string) (userIDs []string, err error) - Take(ctx context.Context, groupID string, userID string) (groupMember *GroupMemberModel, err error) - TakeOwner(ctx context.Context, groupID string) (groupMember *GroupMemberModel, err error) - SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*GroupMemberModel, err error) + Take(ctx context.Context, groupID string, userID string) (groupMember *model.GroupMember, err error) + TakeOwner(ctx context.Context, groupID string) (groupMember *model.GroupMember, err error) + SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*model.GroupMember, err error) FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) - // MapGroupMemberNum(ctx context.Context, groupIDs []string) (count map[string]uint32, err error) - // FindJoinUserID(ctx context.Context, groupIDs []string) (groupUsers map[string][]string, err error) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) TakeGroupMemberNum(ctx context.Context, groupID string) (count int64, err error) - // FindUsersJoinedGroupID(ctx context.Context, userIDs []string) (map[string][]string, error) FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) IsUpdateRoleLevel(data map[string]any) bool } diff --git a/pkg/common/db/table/relation/group_request.go b/pkg/common/storage/database/group_request.go similarity index 55% rename from pkg/common/db/table/relation/group_request.go rename to pkg/common/storage/database/group_request.go index 7e9b258de..7309584f0 100644 --- a/pkg/common/db/table/relation/group_request.go +++ b/pkg/common/storage/database/group_request.go @@ -12,35 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/tools/db/pagination" ) -type GroupRequestModel struct { - UserID string `bson:"user_id"` - GroupID string `bson:"group_id"` - HandleResult int32 `bson:"handle_result"` - ReqMsg string `bson:"req_msg"` - HandledMsg string `bson:"handled_msg"` - ReqTime time.Time `bson:"req_time"` - HandleUserID string `bson:"handle_user_id"` - HandledTime time.Time `bson:"handled_time"` - JoinSource int32 `bson:"join_source"` - InviterUserID string `bson:"inviter_user_id"` - Ex string `bson:"ex"` -} - -type GroupRequestModelInterface interface { - Create(ctx context.Context, groupRequests []*GroupRequestModel) (err error) +type GroupRequest interface { + Create(ctx context.Context, groupRequests []*model.GroupRequest) (err error) Delete(ctx context.Context, groupID string, userID string) (err error) UpdateHandler(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32) (err error) - Take(ctx context.Context, groupID string, userID string) (groupRequest *GroupRequestModel, err error) - FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*GroupRequestModel, error) - Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*GroupRequestModel, err error) - PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*GroupRequestModel, err error) + Take(ctx context.Context, groupID string, userID string) (groupRequest *model.GroupRequest, err error) + FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error) + Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) + PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) } diff --git a/pkg/common/storage/database/log.go b/pkg/common/storage/database/log.go new file mode 100644 index 000000000..383cc5547 --- /dev/null +++ b/pkg/common/storage/database/log.go @@ -0,0 +1,29 @@ +// 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 database + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/tools/db/pagination" + "time" +) + +type Log interface { + Create(ctx context.Context, log []*model.Log) error + Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*model.Log, error) + Delete(ctx context.Context, logID []string, userID string) error + Get(ctx context.Context, logIDs []string, userID string) ([]*model.Log, error) +} diff --git a/pkg/common/db/mgo/black.go b/pkg/common/storage/database/mgo/black.go similarity index 67% rename from pkg/common/db/mgo/black.go rename to pkg/common/storage/database/mgo/black.go index d588aece6..cf74cfab1 100644 --- a/pkg/common/db/mgo/black.go +++ b/pkg/common/storage/database/mgo/black.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" "go.mongodb.org/mongo-driver/bson" @@ -25,7 +26,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewBlackMongo(db *mongo.Database) (relation.BlackModelInterface, error) { +func NewBlackMongo(db *mongo.Database) (database.Black, error) { coll := db.Collection("black") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -51,7 +52,7 @@ func (b *BlackMgo) blackFilter(ownerUserID, blockUserID string) bson.M { } } -func (b *BlackMgo) blacksFilter(blacks []*relation.BlackModel) bson.M { +func (b *BlackMgo) blacksFilter(blacks []*model.Black) bson.M { if len(blacks) == 0 { return nil } @@ -62,11 +63,11 @@ func (b *BlackMgo) blacksFilter(blacks []*relation.BlackModel) bson.M { return bson.M{"$or": or} } -func (b *BlackMgo) Create(ctx context.Context, blacks []*relation.BlackModel) (err error) { +func (b *BlackMgo) Create(ctx context.Context, blacks []*model.Black) (err error) { return mongoutil.InsertMany(ctx, b.coll, blacks) } -func (b *BlackMgo) Delete(ctx context.Context, blacks []*relation.BlackModel) (err error) { +func (b *BlackMgo) Delete(ctx context.Context, blacks []*model.Black) (err error) { if len(blacks) == 0 { return nil } @@ -80,23 +81,23 @@ func (b *BlackMgo) UpdateByMap(ctx context.Context, ownerUserID, blockUserID str return mongoutil.UpdateOne(ctx, b.coll, b.blackFilter(ownerUserID, blockUserID), bson.M{"$set": args}, false) } -func (b *BlackMgo) Find(ctx context.Context, blacks []*relation.BlackModel) (blackList []*relation.BlackModel, err error) { - return mongoutil.Find[*relation.BlackModel](ctx, b.coll, b.blacksFilter(blacks)) +func (b *BlackMgo) Find(ctx context.Context, blacks []*model.Black) (blackList []*model.Black, err error) { + return mongoutil.Find[*model.Black](ctx, b.coll, b.blacksFilter(blacks)) } -func (b *BlackMgo) Take(ctx context.Context, ownerUserID, blockUserID string) (black *relation.BlackModel, err error) { - return mongoutil.FindOne[*relation.BlackModel](ctx, b.coll, b.blackFilter(ownerUserID, blockUserID)) +func (b *BlackMgo) Take(ctx context.Context, ownerUserID, blockUserID string) (black *model.Black, err error) { + return mongoutil.FindOne[*model.Black](ctx, b.coll, b.blackFilter(ownerUserID, blockUserID)) } -func (b *BlackMgo) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*relation.BlackModel, err error) { - return mongoutil.FindPage[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}, pagination) +func (b *BlackMgo) FindOwnerBlacks(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, blacks []*model.Black, err error) { + return mongoutil.FindPage[*model.Black](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}, pagination) } -func (b *BlackMgo) FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*relation.BlackModel, err error) { +func (b *BlackMgo) FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*model.Black, err error) { if len(userIDs) == 0 { - return mongoutil.Find[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}) + return mongoutil.Find[*model.Black](ctx, b.coll, bson.M{"owner_user_id": ownerUserID}) } - return mongoutil.Find[*relation.BlackModel](ctx, b.coll, bson.M{"owner_user_id": ownerUserID, "block_user_id": bson.M{"$in": userIDs}}) + return mongoutil.Find[*model.Black](ctx, b.coll, bson.M{"owner_user_id": ownerUserID, "block_user_id": bson.M{"$in": userIDs}}) } func (b *BlackMgo) FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error) { diff --git a/pkg/common/db/mgo/conversation.go b/pkg/common/storage/database/mgo/conversation.go similarity index 84% rename from pkg/common/db/mgo/conversation.go rename to pkg/common/storage/database/mgo/conversation.go index 5292cb60c..9c35f841b 100644 --- a/pkg/common/db/mgo/conversation.go +++ b/pkg/common/storage/database/mgo/conversation.go @@ -16,9 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" @@ -47,7 +47,7 @@ type ConversationMgo struct { coll *mongo.Collection } -func (c *ConversationMgo) Create(ctx context.Context, conversations []*relation.ConversationModel) (err error) { +func (c *ConversationMgo) Create(ctx context.Context, conversations []*model.Conversation) (err error) { return mongoutil.InsertMany(ctx, c.coll, conversations) } @@ -72,12 +72,12 @@ func (c *ConversationMgo) UpdateByMap(ctx context.Context, userIDs []string, con return res.ModifiedCount, nil } -func (c *ConversationMgo) Update(ctx context.Context, conversation *relation.ConversationModel) (err error) { +func (c *ConversationMgo) Update(ctx context.Context, conversation *model.Conversation) (err error) { return mongoutil.UpdateOne(ctx, c.coll, bson.M{"owner_user_id": conversation.OwnerUserID, "conversation_id": conversation.ConversationID}, bson.M{"$set": conversation}, true) } -func (c *ConversationMgo) Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*relation.ConversationModel, err error) { - return mongoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": ownerUserID, "conversation_id": bson.M{"$in": conversationIDs}}) +func (c *ConversationMgo) Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*model.Conversation, err error) { + return mongoutil.Find[*model.Conversation](ctx, c.coll, bson.M{"owner_user_id": ownerUserID, "conversation_id": bson.M{"$in": conversationIDs}}) } func (c *ConversationMgo) FindUserID(ctx context.Context, userIDs []string, conversationIDs []string) ([]string, error) { @@ -92,16 +92,16 @@ func (c *ConversationMgo) FindUserIDAllConversationID(ctx context.Context, userI return mongoutil.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1})) } -func (c *ConversationMgo) Take(ctx context.Context, userID, conversationID string) (conversation *relation.ConversationModel, err error) { - return mongoutil.FindOne[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": conversationID}) +func (c *ConversationMgo) Take(ctx context.Context, userID, conversationID string) (conversation *model.Conversation, err error) { + return mongoutil.FindOne[*model.Conversation](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": conversationID}) } func (c *ConversationMgo) FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error) { return mongoutil.Find[string](ctx, c.coll, bson.M{"owner_user_id": userID, "conversation_id": bson.M{"$in": conversationIDs}}, options.Find().SetProjection(bson.M{"_id": 0, "conversation_id": 1})) } -func (c *ConversationMgo) FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*relation.ConversationModel, err error) { - return mongoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"owner_user_id": userID}) +func (c *ConversationMgo) FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*model.Conversation, err error) { + return mongoutil.Find[*model.Conversation](ctx, c.coll, bson.M{"owner_user_id": userID}) } func (c *ConversationMgo) FindRecvMsgUserIDs(ctx context.Context, conversationID string, recvOpts []int) ([]string, error) { @@ -144,13 +144,13 @@ func (c *ConversationMgo) PageConversationIDs(ctx context.Context, pagination pa return mongoutil.FindPageOnly[string](ctx, c.coll, bson.M{}, pagination, options.Find().SetProjection(bson.M{"conversation_id": 1})) } -func (c *ConversationMgo) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relation.ConversationModel, error) { - return mongoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{"conversation_id": bson.M{"$in": conversationIDs}}) +func (c *ConversationMgo) GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*model.Conversation, error) { + return mongoutil.Find[*model.Conversation](ctx, c.coll, bson.M{"conversation_id": bson.M{"$in": conversationIDs}}) } -func (c *ConversationMgo) GetConversationIDsNeedDestruct(ctx context.Context) ([]*relation.ConversationModel, error) { +func (c *ConversationMgo) GetConversationIDsNeedDestruct(ctx context.Context) ([]*model.Conversation, error) { // "is_msg_destruct = 1 && msg_destruct_time != 0 && (UNIX_TIMESTAMP(NOW()) > (msg_destruct_time + UNIX_TIMESTAMP(latest_msg_destruct_time)) || latest_msg_destruct_time is NULL)" - return mongoutil.Find[*relation.ConversationModel](ctx, c.coll, bson.M{ + return mongoutil.Find[*model.Conversation](ctx, c.coll, bson.M{ "is_msg_destruct": 1, "msg_destruct_time": bson.M{"$ne": 0}, "$or": []bson.M{ diff --git a/pkg/common/db/mgo/doc.go b/pkg/common/storage/database/mgo/doc.go similarity index 96% rename from pkg/common/db/mgo/doc.go rename to pkg/common/storage/database/mgo/doc.go index f9d43e885..3bc6611ff 100644 --- a/pkg/common/db/mgo/doc.go +++ b/pkg/common/storage/database/mgo/doc.go @@ -12,4 +12,4 @@ // See the License for the specific language governing permissions and // limitations under the License. -package mgo // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo" +package mgo // import "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" diff --git a/pkg/common/db/mgo/friend.go b/pkg/common/storage/database/mgo/friend.go similarity index 80% rename from pkg/common/db/mgo/friend.go rename to pkg/common/storage/database/mgo/friend.go index 269bb594a..ffa006d01 100644 --- a/pkg/common/db/mgo/friend.go +++ b/pkg/common/storage/database/mgo/friend.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" "go.mongodb.org/mongo-driver/bson" @@ -25,13 +26,13 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -// FriendMgo implements FriendModelInterface using MongoDB as the storage backend. +// FriendMgo implements Friend using MongoDB as the storage backend. type FriendMgo struct { coll *mongo.Collection } // NewFriendMongo creates a new instance of FriendMgo with the provided MongoDB database. -func NewFriendMongo(db *mongo.Database) (relation.FriendModelInterface, error) { +func NewFriendMongo(db *mongo.Database) (database.Friend, error) { coll := db.Collection("friend") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -47,7 +48,7 @@ func NewFriendMongo(db *mongo.Database) (relation.FriendModelInterface, error) { } // Create inserts multiple friend records. -func (f *FriendMgo) Create(ctx context.Context, friends []*relation.FriendModel) error { +func (f *FriendMgo) Create(ctx context.Context, friends []*model.Friend) error { return mongoutil.InsertMany(ctx, f.coll, friends) } @@ -73,7 +74,7 @@ func (f *FriendMgo) UpdateByMap(ctx context.Context, ownerUserID string, friendU } // Update modifies multiple friend documents. -// func (f *FriendMgo) Update(ctx context.Context, friends []*relation.FriendModel) error { +// func (f *FriendMgo) Update(ctx context.Context, friends []*relation.Friend) error { // filter := bson.M{ // "owner_user_id": ownerUserID, // "friend_user_id": friendUserID, @@ -87,53 +88,53 @@ func (f *FriendMgo) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, } // Take retrieves a single friend document. Returns an error if not found. -func (f *FriendMgo) Take(ctx context.Context, ownerUserID, friendUserID string) (*relation.FriendModel, error) { +func (f *FriendMgo) Take(ctx context.Context, ownerUserID, friendUserID string) (*model.Friend, error) { filter := bson.M{ "owner_user_id": ownerUserID, "friend_user_id": friendUserID, } - return mongoutil.FindOne[*relation.FriendModel](ctx, f.coll, filter) + return mongoutil.FindOne[*model.Friend](ctx, f.coll, filter) } // FindUserState finds the friendship status between two users. -func (f *FriendMgo) FindUserState(ctx context.Context, userID1, userID2 string) ([]*relation.FriendModel, error) { +func (f *FriendMgo) FindUserState(ctx context.Context, userID1, userID2 string) ([]*model.Friend, error) { filter := bson.M{ "$or": []bson.M{ {"owner_user_id": userID1, "friend_user_id": userID2}, {"owner_user_id": userID2, "friend_user_id": userID1}, }, } - return mongoutil.Find[*relation.FriendModel](ctx, f.coll, filter) + return mongoutil.Find[*model.Friend](ctx, f.coll, filter) } // FindFriends retrieves a list of friends for a given owner. Missing friends do not cause an error. -func (f *FriendMgo) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) ([]*relation.FriendModel, error) { +func (f *FriendMgo) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) ([]*model.Friend, error) { filter := bson.M{ "owner_user_id": ownerUserID, "friend_user_id": bson.M{"$in": friendUserIDs}, } - return mongoutil.Find[*relation.FriendModel](ctx, f.coll, filter) + return mongoutil.Find[*model.Friend](ctx, f.coll, filter) } // FindReversalFriends finds users who have added the specified user as a friend. -func (f *FriendMgo) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) ([]*relation.FriendModel, error) { +func (f *FriendMgo) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) ([]*model.Friend, error) { filter := bson.M{ "owner_user_id": bson.M{"$in": ownerUserIDs}, "friend_user_id": friendUserID, } - return mongoutil.Find[*relation.FriendModel](ctx, f.coll, filter) + return mongoutil.Find[*model.Friend](ctx, f.coll, filter) } // FindOwnerFriends retrieves a paginated list of friends for a given owner. -func (f *FriendMgo) FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (int64, []*relation.FriendModel, error) { +func (f *FriendMgo) FindOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (int64, []*model.Friend, error) { filter := bson.M{"owner_user_id": ownerUserID} - return mongoutil.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination) + return mongoutil.FindPage[*model.Friend](ctx, f.coll, filter, pagination) } // FindInWhoseFriends finds users who have added the specified user as a friend, with pagination. -func (f *FriendMgo) FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (int64, []*relation.FriendModel, error) { +func (f *FriendMgo) FindInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (int64, []*model.Friend, error) { filter := bson.M{"friend_user_id": friendUserID} - return mongoutil.FindPage[*relation.FriendModel](ctx, f.coll, filter, pagination) + return mongoutil.FindPage[*model.Friend](ctx, f.coll, filter, pagination) } // FindFriendUserIDs retrieves a list of friend user IDs for a given owner. diff --git a/pkg/common/db/mgo/friend_request.go b/pkg/common/storage/database/mgo/friend_request.go similarity index 76% rename from pkg/common/db/mgo/friend_request.go rename to pkg/common/storage/database/mgo/friend_request.go index 704b68126..0d60b213d 100644 --- a/pkg/common/db/mgo/friend_request.go +++ b/pkg/common/storage/database/mgo/friend_request.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" "go.mongodb.org/mongo-driver/bson" @@ -25,7 +26,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewFriendRequestMongo(db *mongo.Database) (relation.FriendRequestModelInterface, error) { +func NewFriendRequestMongo(db *mongo.Database) (database.FriendRequest, error) { coll := db.Collection("friend_request") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -44,23 +45,23 @@ type FriendRequestMgo struct { coll *mongo.Collection } -func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*relation.FriendRequestModel, err error) { - return mongoutil.FindPage[*relation.FriendRequestModel](ctx, f.coll, bson.M{"to_user_id": toUserID}, pagination) +func (f *FriendRequestMgo) FindToUserID(ctx context.Context, toUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) { + return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, bson.M{"to_user_id": toUserID}, pagination) } -func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*relation.FriendRequestModel, err error) { - return mongoutil.FindPage[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID}, pagination) +func (f *FriendRequestMgo) FindFromUserID(ctx context.Context, fromUserID string, pagination pagination.Pagination) (total int64, friendRequests []*model.FriendRequest, err error) { + return mongoutil.FindPage[*model.FriendRequest](ctx, f.coll, bson.M{"from_user_id": fromUserID}, pagination) } -func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*relation.FriendRequestModel, err error) { +func (f *FriendRequestMgo) FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*model.FriendRequest, err error) { filter := bson.M{"$or": []bson.M{ {"from_user_id": fromUserID, "to_user_id": toUserID}, {"from_user_id": toUserID, "to_user_id": fromUserID}, }} - return mongoutil.Find[*relation.FriendRequestModel](ctx, f.coll, filter) + return mongoutil.Find[*model.FriendRequest](ctx, f.coll, filter) } -func (f *FriendRequestMgo) Create(ctx context.Context, friendRequests []*relation.FriendRequestModel) error { +func (f *FriendRequestMgo) Create(ctx context.Context, friendRequests []*model.FriendRequest) error { return mongoutil.InsertMany(ctx, f.coll, friendRequests) } @@ -75,7 +76,7 @@ func (f *FriendRequestMgo) UpdateByMap(ctx context.Context, formUserID, toUserID return mongoutil.UpdateOne(ctx, f.coll, bson.M{"from_user_id": formUserID, "to_user_id": toUserID}, bson.M{"$set": args}, true) } -func (f *FriendRequestMgo) Update(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { +func (f *FriendRequestMgo) Update(ctx context.Context, friendRequest *model.FriendRequest) (err error) { updater := bson.M{} if friendRequest.HandleResult != 0 { updater["handle_result"] = friendRequest.HandleResult @@ -102,10 +103,10 @@ func (f *FriendRequestMgo) Update(ctx context.Context, friendRequest *relation.F return mongoutil.UpdateOne(ctx, f.coll, filter, bson.M{"$set": updater}, true) } -func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) { - return mongoutil.FindOne[*relation.FriendRequestModel](ctx, f.coll, bson.M{"from_user_id": fromUserID, "to_user_id": toUserID}) +func (f *FriendRequestMgo) Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) { + return mongoutil.FindOne[*model.FriendRequest](ctx, f.coll, bson.M{"from_user_id": fromUserID, "to_user_id": toUserID}) } -func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *relation.FriendRequestModel, err error) { +func (f *FriendRequestMgo) Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *model.FriendRequest, err error) { return f.Find(ctx, fromUserID, toUserID) } diff --git a/pkg/common/db/mgo/group.go b/pkg/common/storage/database/mgo/group.go similarity index 82% rename from pkg/common/db/mgo/group.go rename to pkg/common/storage/database/mgo/group.go index 0169c2339..48d24560b 100644 --- a/pkg/common/db/mgo/group.go +++ b/pkg/common/storage/database/mgo/group.go @@ -16,9 +16,10 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" @@ -28,7 +29,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewGroupMongo(db *mongo.Database) (relation.GroupModelInterface, error) { +func NewGroupMongo(db *mongo.Database) (database.Group, error) { coll := db.Collection("group") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -46,7 +47,7 @@ type GroupMgo struct { coll *mongo.Collection } -func (g *GroupMgo) Create(ctx context.Context, groups []*relation.GroupModel) (err error) { +func (g *GroupMgo) Create(ctx context.Context, groups []*model.Group) (err error) { return mongoutil.InsertMany(ctx, g.coll, groups) } @@ -61,20 +62,20 @@ func (g *GroupMgo) UpdateMap(ctx context.Context, groupID string, args map[strin return mongoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID}, bson.M{"$set": args}, true) } -func (g *GroupMgo) Find(ctx context.Context, groupIDs []string) (groups []*relation.GroupModel, err error) { - return mongoutil.Find[*relation.GroupModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}) +func (g *GroupMgo) Find(ctx context.Context, groupIDs []string) (groups []*model.Group, err error) { + return mongoutil.Find[*model.Group](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}) } -func (g *GroupMgo) Take(ctx context.Context, groupID string) (group *relation.GroupModel, err error) { - return mongoutil.FindOne[*relation.GroupModel](ctx, g.coll, bson.M{"group_id": groupID}) +func (g *GroupMgo) Take(ctx context.Context, groupID string) (group *model.Group, err error) { + return mongoutil.FindOne[*model.Group](ctx, g.coll, bson.M{"group_id": groupID}) } -func (g *GroupMgo) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*relation.GroupModel, err error) { +func (g *GroupMgo) Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*model.Group, err error) { // Define the sorting options opts := options.Find().SetSort(bson.D{{Key: "created_at", Value: -1}}) // Perform the search with pagination and sorting - return mongoutil.FindPage[*relation.GroupModel](ctx, g.coll, bson.M{ + return mongoutil.FindPage[*model.Group](ctx, g.coll, bson.M{ "group_name": bson.M{"$regex": keyword}, "status": bson.M{"$ne": constant.GroupStatusDismissed}, }, pagination, opts) diff --git a/pkg/common/db/mgo/group_member.go b/pkg/common/storage/database/mgo/group_member.go similarity index 83% rename from pkg/common/db/mgo/group_member.go rename to pkg/common/storage/database/mgo/group_member.go index 29d69d0f0..ccca386e5 100644 --- a/pkg/common/db/mgo/group_member.go +++ b/pkg/common/storage/database/mgo/group_member.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" @@ -27,7 +28,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewGroupMember(db *mongo.Database) (relation.GroupMemberModelInterface, error) { +func NewGroupMember(db *mongo.Database) (database.GroupMember, error) { coll := db.Collection("group_member") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -46,7 +47,7 @@ type GroupMemberMgo struct { coll *mongo.Collection } -func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*relation.GroupMemberModel) (err error) { +func (g *GroupMemberMgo) Create(ctx context.Context, groupMembers []*model.GroupMember) (err error) { return mongoutil.InsertMany(ctx, g.coll, groupMembers) } @@ -66,7 +67,7 @@ func (g *GroupMemberMgo) Update(ctx context.Context, groupID string, userID stri return mongoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": data}, true) } -func (g *GroupMemberMgo) Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (groupMembers []*relation.GroupMemberModel, err error) { +func (g *GroupMemberMgo) Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) (groupMembers []*model.GroupMember, err error) { // TODO implement me panic("implement me") } @@ -75,21 +76,21 @@ func (g *GroupMemberMgo) FindMemberUserID(ctx context.Context, groupID string) ( return mongoutil.Find[string](ctx, g.coll, bson.M{"group_id": groupID}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1})) } -func (g *GroupMemberMgo) Take(ctx context.Context, groupID string, userID string) (groupMember *relation.GroupMemberModel, err error) { - return mongoutil.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) +func (g *GroupMemberMgo) Take(ctx context.Context, groupID string, userID string) (groupMember *model.GroupMember, err error) { + return mongoutil.FindOne[*model.GroupMember](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) } -func (g *GroupMemberMgo) TakeOwner(ctx context.Context, groupID string) (groupMember *relation.GroupMemberModel, err error) { - return mongoutil.FindOne[*relation.GroupMemberModel](ctx, g.coll, bson.M{"group_id": groupID, "role_level": constant.GroupOwner}) +func (g *GroupMemberMgo) TakeOwner(ctx context.Context, groupID string) (groupMember *model.GroupMember, err error) { + return mongoutil.FindOne[*model.GroupMember](ctx, g.coll, bson.M{"group_id": groupID, "role_level": constant.GroupOwner}) } func (g *GroupMemberMgo) FindRoleLevelUserIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) { return mongoutil.Find[string](ctx, g.coll, bson.M{"group_id": groupID, "role_level": roleLevel}, options.Find().SetProjection(bson.M{"_id": 0, "user_id": 1})) } -func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*relation.GroupMemberModel, err error) { +func (g *GroupMemberMgo) SearchMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (total int64, groupList []*model.GroupMember, err error) { filter := bson.M{"group_id": groupID, "nickname": bson.M{"$regex": keyword}} - return mongoutil.FindPage[*relation.GroupMemberModel](ctx, g.coll, filter, pagination) + return mongoutil.FindPage[*model.GroupMember](ctx, g.coll, filter, pagination) } func (g *GroupMemberMgo) FindUserJoinedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) { diff --git a/pkg/common/db/mgo/group_request.go b/pkg/common/storage/database/mgo/group_request.go similarity index 69% rename from pkg/common/db/mgo/group_request.go rename to pkg/common/storage/database/mgo/group_request.go index 17cbeab17..4ae778527 100644 --- a/pkg/common/db/mgo/group_request.go +++ b/pkg/common/storage/database/mgo/group_request.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" "github.com/openimsdk/tools/errs" @@ -26,7 +27,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewGroupRequestMgo(db *mongo.Database) (relation.GroupRequestModelInterface, error) { +func NewGroupRequestMgo(db *mongo.Database) (database.GroupRequest, error) { coll := db.Collection("group_request") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -45,7 +46,7 @@ type GroupRequestMgo struct { coll *mongo.Collection } -func (g *GroupRequestMgo) Create(ctx context.Context, groupRequests []*relation.GroupRequestModel) (err error) { +func (g *GroupRequestMgo) Create(ctx context.Context, groupRequests []*model.GroupRequest) (err error) { return mongoutil.InsertMany(ctx, g.coll, groupRequests) } @@ -57,18 +58,18 @@ func (g *GroupRequestMgo) UpdateHandler(ctx context.Context, groupID string, use return mongoutil.UpdateOne(ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}, bson.M{"$set": bson.M{"handle_msg": handledMsg, "handle_result": handleResult}}, true) } -func (g *GroupRequestMgo) Take(ctx context.Context, groupID string, userID string) (groupRequest *relation.GroupRequestModel, err error) { - return mongoutil.FindOne[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) +func (g *GroupRequestMgo) Take(ctx context.Context, groupID string, userID string) (groupRequest *model.GroupRequest, err error) { + return mongoutil.FindOne[*model.GroupRequest](ctx, g.coll, bson.M{"group_id": groupID, "user_id": userID}) } -func (g *GroupRequestMgo) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relation.GroupRequestModel, error) { - return mongoutil.Find[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}}) +func (g *GroupRequestMgo) FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*model.GroupRequest, error) { + return mongoutil.Find[*model.GroupRequest](ctx, g.coll, bson.M{"group_id": groupID, "user_id": bson.M{"$in": userIDs}}) } -func (g *GroupRequestMgo) Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*relation.GroupRequestModel, err error) { - return mongoutil.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"user_id": userID}, pagination) +func (g *GroupRequestMgo) Page(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) { + return mongoutil.FindPage[*model.GroupRequest](ctx, g.coll, bson.M{"user_id": userID}, pagination) } -func (g *GroupRequestMgo) PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*relation.GroupRequestModel, err error) { - return mongoutil.FindPage[*relation.GroupRequestModel](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}, pagination) +func (g *GroupRequestMgo) PageGroup(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (total int64, groups []*model.GroupRequest, err error) { + return mongoutil.FindPage[*model.GroupRequest](ctx, g.coll, bson.M{"group_id": bson.M{"$in": groupIDs}}, pagination) } diff --git a/pkg/common/db/table/relation/utils.go b/pkg/common/storage/database/mgo/helpers.go similarity index 80% rename from pkg/common/db/table/relation/utils.go rename to pkg/common/storage/database/mgo/helpers.go index 006da4808..23e66236a 100644 --- a/pkg/common/db/table/relation/utils.go +++ b/pkg/common/storage/database/mgo/helpers.go @@ -12,24 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package mgo import ( "github.com/openimsdk/tools/errs" "go.mongodb.org/mongo-driver/mongo" ) -type BatchUpdateGroupMember struct { - GroupID string - UserID string - Map map[string]any -} - -type GroupSimpleUserID struct { - Hash uint64 - MemberNum uint32 -} - func IsNotFound(err error) bool { return errs.Unwrap(err) == mongo.ErrNoDocuments } diff --git a/pkg/common/db/mgo/log.go b/pkg/common/storage/database/mgo/log.go similarity index 75% rename from pkg/common/db/mgo/log.go rename to pkg/common/storage/database/mgo/log.go index 36a0bbbc5..51715bd77 100644 --- a/pkg/common/db/mgo/log.go +++ b/pkg/common/storage/database/mgo/log.go @@ -16,9 +16,10 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" "go.mongodb.org/mongo-driver/bson" @@ -26,7 +27,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewLogMongo(db *mongo.Database) (relation.LogInterface, error) { +func NewLogMongo(db *mongo.Database) (database.Log, error) { coll := db.Collection("log") _, err := coll.Indexes().CreateMany(context.Background(), []mongo.IndexModel{ { @@ -56,16 +57,16 @@ type LogMgo struct { coll *mongo.Collection } -func (l *LogMgo) Create(ctx context.Context, log []*relation.LogModel) error { +func (l *LogMgo) Create(ctx context.Context, log []*model.Log) error { return mongoutil.InsertMany(ctx, l.coll, log) } -func (l *LogMgo) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*relation.LogModel, error) { +func (l *LogMgo) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*model.Log, error) { filter := bson.M{"create_time": bson.M{"$gte": start, "$lte": end}} if keyword != "" { filter["user_id"] = bson.M{"$regex": keyword} } - return mongoutil.FindPage[*relation.LogModel](ctx, l.coll, filter, pagination, options.Find().SetSort(bson.M{"create_time": -1})) + return mongoutil.FindPage[*model.Log](ctx, l.coll, filter, pagination, options.Find().SetSort(bson.M{"create_time": -1})) } func (l *LogMgo) Delete(ctx context.Context, logID []string, userID string) error { @@ -75,9 +76,9 @@ func (l *LogMgo) Delete(ctx context.Context, logID []string, userID string) erro return mongoutil.DeleteMany(ctx, l.coll, bson.M{"log_id": bson.M{"$in": logID}, "user_id": userID}) } -func (l *LogMgo) Get(ctx context.Context, logIDs []string, userID string) ([]*relation.LogModel, error) { +func (l *LogMgo) Get(ctx context.Context, logIDs []string, userID string) ([]*model.Log, error) { if userID == "" { - return mongoutil.Find[*relation.LogModel](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}}) + return mongoutil.Find[*model.Log](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}}) } - return mongoutil.Find[*relation.LogModel](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}, "user_id": userID}) + return mongoutil.Find[*model.Log](ctx, l.coll, bson.M{"log_id": bson.M{"$in": logIDs}, "user_id": userID}) } diff --git a/pkg/common/db/mgo/msg.go b/pkg/common/storage/database/mgo/msg.go similarity index 91% rename from pkg/common/db/mgo/msg.go rename to pkg/common/storage/database/mgo/msg.go index 17e493d33..f676c1f59 100644 --- a/pkg/common/db/mgo/msg.go +++ b/pkg/common/storage/database/mgo/msg.go @@ -3,9 +3,10 @@ package mgo import ( "context" "fmt" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/constant" "github.com/openimsdk/protocol/msg" "github.com/openimsdk/protocol/sdkws" @@ -19,8 +20,8 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewMsgMongo(db *mongo.Database) (relation.MsgDocModelInterface, error) { - coll := db.Collection(new(relation.MsgDocModel).TableName()) +func NewMsgMongo(db *mongo.Database) (database.Msg, error) { + coll := db.Collection(new(model.MsgDocModel).TableName()) _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ {Key: "doc_id", Value: 1}, @@ -35,17 +36,17 @@ func NewMsgMongo(db *mongo.Database) (relation.MsgDocModelInterface, error) { type MsgMgo struct { coll *mongo.Collection - model relation.MsgDocModel + model model.MsgDocModel } -func (m *MsgMgo) PushMsgsToDoc(ctx context.Context, docID string, msgsToMongo []relation.MsgInfoModel) error { +func (m *MsgMgo) PushMsgsToDoc(ctx context.Context, docID string, msgsToMongo []model.MsgInfoModel) error { filter := bson.M{"doc_id": docID} update := bson.M{"$push": bson.M{"msgs": bson.M{"$each": msgsToMongo}}} return mongoutil.UpdateOne(ctx, m.coll, filter, update, false) } -func (m *MsgMgo) Create(ctx context.Context, model *relation.MsgDocModel) error { - return mongoutil.InsertMany(ctx, m.coll, []*relation.MsgDocModel{model}) +func (m *MsgMgo) Create(ctx context.Context, msg *model.MsgDocModel) error { + return mongoutil.InsertMany(ctx, m.coll, []*model.MsgDocModel{msg}) } func (m *MsgMgo) UpdateMsg(ctx context.Context, docID string, index int64, key string, value any) (*mongo.UpdateResult, error) { @@ -86,11 +87,11 @@ func (m *MsgMgo) IsExistDocID(ctx context.Context, docID string) (bool, error) { return mongoutil.Exist(ctx, m.coll, bson.M{"doc_id": docID}) } -func (m *MsgMgo) FindOneByDocID(ctx context.Context, docID string) (*relation.MsgDocModel, error) { - return mongoutil.FindOne[*relation.MsgDocModel](ctx, m.coll, bson.M{"doc_id": docID}) +func (m *MsgMgo) FindOneByDocID(ctx context.Context, docID string) (*model.MsgDocModel, error) { + return mongoutil.FindOne[*model.MsgDocModel](ctx, m.coll, bson.M{"doc_id": docID}) } -func (m *MsgMgo) GetMsgBySeqIndexIn1Doc(ctx context.Context, userID, docID string, seqs []int64) ([]*relation.MsgInfoModel, error) { +func (m *MsgMgo) GetMsgBySeqIndexIn1Doc(ctx context.Context, userID, docID string, seqs []int64) ([]*model.MsgInfoModel, error) { indexs := make([]int64, 0, len(seqs)) for _, seq := range seqs { indexs = append(indexs, m.model.GetMsgIndex(seq)) @@ -131,14 +132,14 @@ func (m *MsgMgo) GetMsgBySeqIndexIn1Doc(ctx context.Context, userID, docID strin {Key: "msgs.del_list", Value: 0}, }}}, } - msgDocModel, err := mongoutil.Aggregate[*relation.MsgDocModel](ctx, m.coll, pipeline) + msgDocModel, err := mongoutil.Aggregate[*model.MsgDocModel](ctx, m.coll, pipeline) if err != nil { return nil, err } if len(msgDocModel) == 0 { return nil, errs.Wrap(mongo.ErrNoDocuments) } - msgs := make([]*relation.MsgInfoModel, 0, len(msgDocModel[0].Msg)) + msgs := make([]*model.MsgInfoModel, 0, len(msgDocModel[0].Msg)) for i := range msgDocModel[0].Msg { msg := msgDocModel[0].Msg[i] if msg == nil || msg.Msg == nil { @@ -177,7 +178,7 @@ func (m *MsgMgo) GetMsgBySeqIndexIn1Doc(ctx context.Context, userID, docID strin return msgs, nil } -func (m *MsgMgo) GetNewestMsg(ctx context.Context, conversationID string) (*relation.MsgInfoModel, error) { +func (m *MsgMgo) GetNewestMsg(ctx context.Context, conversationID string) (*model.MsgInfoModel, error) { for skip := int64(0); ; skip++ { msgDocModel, err := m.GetMsgDocModelByIndex(ctx, conversationID, skip, -1) if err != nil { @@ -191,7 +192,7 @@ func (m *MsgMgo) GetNewestMsg(ctx context.Context, conversationID string) (*rela } } -func (m *MsgMgo) GetOldestMsg(ctx context.Context, conversationID string) (*relation.MsgInfoModel, error) { +func (m *MsgMgo) GetOldestMsg(ctx context.Context, conversationID string) (*model.MsgInfoModel, error) { for skip := int64(0); ; skip++ { msgDocModel, err := m.GetMsgDocModelByIndex(ctx, conversationID, skip, 1) if err != nil { @@ -212,20 +213,20 @@ func (m *MsgMgo) DeleteDocs(ctx context.Context, docIDs []string) error { return mongoutil.DeleteMany(ctx, m.coll, bson.M{"doc_id": bson.M{"$in": docIDs}}) } -func (m *MsgMgo) GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*relation.MsgDocModel, error) { +func (m *MsgMgo) GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*model.MsgDocModel, error) { if sort != 1 && sort != -1 { return nil, errs.ErrArgs.WrapMsg("mongo sort must be 1 or -1") } opt := options.Find().SetLimit(1).SetSkip(index).SetSort(bson.M{"doc_id": sort}).SetLimit(1) filter := bson.M{"doc_id": primitive.Regex{Pattern: fmt.Sprintf("^%s:", conversationID)}} - msgs, err := mongoutil.Find[*relation.MsgDocModel](ctx, m.coll, filter, opt) + msgs, err := mongoutil.Find[*model.MsgDocModel](ctx, m.coll, filter, opt) if err != nil { return nil, err } if len(msgs) > 0 { return msgs[0], nil } - return nil, errs.Wrap(relation.ErrMsgListNotExist) + return nil, errs.Wrap(model.ErrMsgListNotExist) } func (m *MsgMgo) DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error { @@ -266,7 +267,7 @@ func (m *MsgMgo) MarkSingleChatMsgsAsRead(ctx context.Context, userID string, do return nil } -func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*relation.MsgInfoModel, error) { +func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*model.MsgInfoModel, error) { where := make(bson.A, 0, 6) if req.RecvID != "" { where = append(where, bson.M{"msgs.msg.recv_id": req.RecvID}) @@ -335,7 +336,7 @@ func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ( "$limit": req.Pagination.GetShowNumber(), }, ) - msgs, err := mongoutil.Aggregate[*relation.MsgInfoModel](ctx, m.coll, pipeline) + msgs, err := mongoutil.Aggregate[*model.MsgInfoModel](ctx, m.coll, pipeline) if err != nil { return 0, nil, err } @@ -385,7 +386,7 @@ func (m *MsgMgo) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ( return count[0], msgs, nil } -func (m *MsgMgo) RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*relation.UserCount, dateCount map[string]int64, err error) { +func (m *MsgMgo) RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*model.UserCount, dateCount map[string]int64, err error) { var sort int if ase { sort = 1 @@ -619,9 +620,9 @@ func (m *MsgMgo) RangeUserSendCount(ctx context.Context, start time.Time, end ti if len(result) == 0 { return 0, 0, nil, nil, errs.Wrap(err) } - users = make([]*relation.UserCount, len(result[0].Users)) + users = make([]*model.UserCount, len(result[0].Users)) for i, r := range result[0].Users { - users[i] = &relation.UserCount{ + users[i] = &model.UserCount{ UserID: r.UserID, Count: r.Count, } @@ -633,7 +634,7 @@ func (m *MsgMgo) RangeUserSendCount(ctx context.Context, start time.Time, end ti return result[0].MsgCount, result[0].UserCount, users, dateCount, nil } -func (m *MsgMgo) RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*relation.GroupCount, dateCount map[string]int64, err error) { +func (m *MsgMgo) RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*model.GroupCount, dateCount map[string]int64, err error) { var sort int if ase { sort = 1 @@ -856,9 +857,9 @@ func (m *MsgMgo) RangeGroupSendCount(ctx context.Context, start time.Time, end t if len(result) == 0 { return 0, 0, nil, nil, errs.Wrap(err) } - groups = make([]*relation.GroupCount, len(result[0].Groups)) + groups = make([]*model.GroupCount, len(result[0].Groups)) for i, r := range result[0].Groups { - groups[i] = &relation.GroupCount{ + groups[i] = &model.GroupCount{ GroupID: r.GroupID, Count: r.Count, } @@ -873,7 +874,7 @@ func (m *MsgMgo) RangeGroupSendCount(ctx context.Context, start time.Time, end t func (m *MsgMgo) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) { for _, conversationID := range conversationIDs { regex := primitive.Regex{Pattern: fmt.Sprintf("^%s:", conversationID)} - msgDocs, err := mongoutil.Find[*relation.MsgDocModel](ctx, m.coll, bson.M{"doc_id": regex}) + msgDocs, err := mongoutil.Find[*model.MsgDocModel](ctx, m.coll, bson.M{"doc_id": regex}) if err != nil { log.ZError(ctx, "convertAll find msg doc failed", err, "conversationID", conversationID) continue @@ -896,7 +897,7 @@ func (m *MsgMgo) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string for index < int64(len(msgDoc.Msg)) { msg := msgDoc.Msg[index] if msg != nil && msg.Msg != nil { - msgDocModel := relation.MsgDocModel{DocID: m.model.GetDocID(conversationID, msg.Msg.Seq)} + msgDocModel := model.MsgDocModel{DocID: m.model.GetDocID(conversationID, msg.Msg.Seq)} end := index + m.model.GetSingleGocMsgNum() if int(end) >= len(msgDoc.Msg) { msgDocModel.Msg = msgDoc.Msg[index:] @@ -919,8 +920,8 @@ func (m *MsgMgo) ConvertMsgsDocLen(ctx context.Context, conversationIDs []string } } -func (m *MsgMgo) GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*relation.MsgDocModel, error) { - return mongoutil.Aggregate[*relation.MsgDocModel](ctx, m.coll, []bson.M{ +func (m *MsgMgo) GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) { + return mongoutil.Aggregate[*model.MsgDocModel](ctx, m.coll, []bson.M{ { "$match": bson.M{ "msgs.msg.send_time": bson.M{ @@ -946,7 +947,7 @@ func (m *MsgMgo) DeleteMsgByIndex(ctx context.Context, docID string, index []int if len(index) == 0 { return nil } - model := &relation.MsgInfoModel{DelList: []string{}} + model := &model.MsgInfoModel{DelList: []string{}} set := make(map[string]any) for i := range index { set[fmt.Sprintf("msgs.%d", i)] = model diff --git a/pkg/common/db/mgo/object.go b/pkg/common/storage/database/mgo/object.go similarity index 79% rename from pkg/common/db/mgo/object.go rename to pkg/common/storage/database/mgo/object.go index 1c628bb51..8ed7b3a56 100644 --- a/pkg/common/db/mgo/object.go +++ b/pkg/common/storage/database/mgo/object.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/errs" "go.mongodb.org/mongo-driver/bson" @@ -25,7 +26,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewS3Mongo(db *mongo.Database) (relation.ObjectInfoModelInterface, error) { +func NewS3Mongo(db *mongo.Database) (database.ObjectInfo, error) { coll := db.Collection("s3") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -43,7 +44,7 @@ type S3Mongo struct { coll *mongo.Collection } -func (o *S3Mongo) SetObject(ctx context.Context, obj *relation.ObjectModel) error { +func (o *S3Mongo) SetObject(ctx context.Context, obj *model.Object) error { filter := bson.M{"name": obj.Name, "engine": obj.Engine} update := bson.M{ "name": obj.Name, @@ -57,11 +58,11 @@ func (o *S3Mongo) SetObject(ctx context.Context, obj *relation.ObjectModel) erro return mongoutil.UpdateOne(ctx, o.coll, filter, bson.M{"$set": update}, false, options.Update().SetUpsert(true)) } -func (o *S3Mongo) Take(ctx context.Context, engine string, name string) (*relation.ObjectModel, error) { +func (o *S3Mongo) Take(ctx context.Context, engine string, name string) (*model.Object, error) { if engine == "" { - return mongoutil.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name}) + return mongoutil.FindOne[*model.Object](ctx, o.coll, bson.M{"name": name}) } - return mongoutil.FindOne[*relation.ObjectModel](ctx, o.coll, bson.M{"name": name, "engine": engine}) + return mongoutil.FindOne[*model.Object](ctx, o.coll, bson.M{"name": name, "engine": engine}) } func (o *S3Mongo) Delete(ctx context.Context, engine string, name string) error { diff --git a/pkg/common/db/mgo/subscribe.go b/pkg/common/storage/database/mgo/subscribe.go similarity index 93% rename from pkg/common/db/mgo/subscribe.go rename to pkg/common/storage/database/mgo/subscribe.go index f2057dc45..5b7d9786b 100644 --- a/pkg/common/db/mgo/subscribe.go +++ b/pkg/common/storage/database/mgo/subscribe.go @@ -16,8 +16,9 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/tools/errs" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/mongo" @@ -35,9 +36,9 @@ const ( MaximumSubscription = 3000 ) -func NewUserMongoDriver(database *mongo.Database) relation.SubscribeUserModelInterface { +func NewUserMongoDriver(database *mongo.Database) database.SubscribeUser { return &UserMongoDriver{ - userCollection: database.Collection(relation.SubscribeUser), + userCollection: database.Collection(model.SubscribeUserTableName), } } @@ -155,7 +156,7 @@ func (u *UserMongoDriver) RemoveSubscribedListFromUser(ctx context.Context, user // GetAllSubscribeList Get all users subscribed by this user. func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string) (userIDList []string, err error) { - var user relation.SubscribeUserModel + var user model.SubscribeUser cursor := u.userCollection.FindOne( ctx, bson.M{"user_id": SubscriptionPrefix + userID}) @@ -172,7 +173,7 @@ func (u *UserMongoDriver) GetAllSubscribeList(ctx context.Context, userID string // GetSubscribedList Get the user subscribed by those users. func (u *UserMongoDriver) GetSubscribedList(ctx context.Context, userID string) (userIDList []string, err error) { - var user relation.SubscribeUserModel + var user model.SubscribeUser cursor := u.userCollection.FindOne( ctx, bson.M{"user_id": SubscribedPrefix + userID}) diff --git a/pkg/common/db/mgo/user.go b/pkg/common/storage/database/mgo/user.go similarity index 87% rename from pkg/common/db/mgo/user.go rename to pkg/common/storage/database/mgo/user.go index 696479871..96cb18882 100644 --- a/pkg/common/db/mgo/user.go +++ b/pkg/common/storage/database/mgo/user.go @@ -16,9 +16,10 @@ package mgo import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/database" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "time" - "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation" "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/db/mongoutil" "github.com/openimsdk/tools/db/pagination" @@ -29,7 +30,7 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" ) -func NewUserMongo(db *mongo.Database) (relation.UserModelInterface, error) { +func NewUserMongo(db *mongo.Database) (database.User, error) { coll := db.Collection("user") _, err := coll.Indexes().CreateOne(context.Background(), mongo.IndexModel{ Keys: bson.D{ @@ -47,7 +48,7 @@ type UserMgo struct { coll *mongo.Collection } -func (u *UserMgo) Create(ctx context.Context, users []*relation.UserModel) error { +func (u *UserMgo) Create(ctx context.Context, users []*model.User) error { return mongoutil.InsertMany(ctx, u.coll, users) } @@ -58,27 +59,27 @@ func (u *UserMgo) UpdateByMap(ctx context.Context, userID string, args map[strin return mongoutil.UpdateOne(ctx, u.coll, bson.M{"user_id": userID}, bson.M{"$set": args}, true) } -func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*relation.UserModel, err error) { - return mongoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"user_id": bson.M{"$in": userIDs}}) +func (u *UserMgo) Find(ctx context.Context, userIDs []string) (users []*model.User, err error) { + return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"user_id": bson.M{"$in": userIDs}}) } -func (u *UserMgo) Take(ctx context.Context, userID string) (user *relation.UserModel, err error) { - return mongoutil.FindOne[*relation.UserModel](ctx, u.coll, bson.M{"user_id": userID}) +func (u *UserMgo) Take(ctx context.Context, userID string) (user *model.User, err error) { + return mongoutil.FindOne[*model.User](ctx, u.coll, bson.M{"user_id": userID}) } -func (u *UserMgo) TakeNotification(ctx context.Context, level int64) (user []*relation.UserModel, err error) { - return mongoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"app_manger_level": level}) +func (u *UserMgo) TakeNotification(ctx context.Context, level int64) (user []*model.User, err error) { + return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"app_manger_level": level}) } -func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*relation.UserModel, err error) { - return mongoutil.Find[*relation.UserModel](ctx, u.coll, bson.M{"nickname": nickname}) +func (u *UserMgo) TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error) { + return mongoutil.Find[*model.User](ctx, u.coll, bson.M{"nickname": nickname}) } -func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { - return mongoutil.FindPage[*relation.UserModel](ctx, u.coll, bson.M{}, pagination) +func (u *UserMgo) Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error) { + return mongoutil.FindPage[*model.User](ctx, u.coll, bson.M{}, pagination) } -func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*relation.UserModel, err error) { +func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error) { query := bson.M{ "$or": []bson.M{ {"app_manger_level": level1}, @@ -86,7 +87,7 @@ func (u *UserMgo) PageFindUser(ctx context.Context, level1 int64, level2 int64, }, } - return mongoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) + return mongoutil.FindPage[*model.User](ctx, u.coll, query, pagination) } func (u *UserMgo) PageFindUserWithKeyword( @@ -96,7 +97,7 @@ func (u *UserMgo) PageFindUserWithKeyword( userID string, nickName string, pagination pagination.Pagination, -) (count int64, users []*relation.UserModel, err error) { +) (count int64, users []*model.User, err error) { // Initialize the base query with level conditions query := bson.M{ "$and": []bson.M{ @@ -121,7 +122,7 @@ func (u *UserMgo) PageFindUserWithKeyword( } // Perform the paginated search - return mongoutil.FindPage[*relation.UserModel](ctx, u.coll, query, pagination) + return mongoutil.FindPage[*model.User](ctx, u.coll, query, pagination) } func (u *UserMgo) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (int64, []string, error) { diff --git a/pkg/common/storage/database/msg.go b/pkg/common/storage/database/msg.go new file mode 100644 index 000000000..b402f3ac7 --- /dev/null +++ b/pkg/common/storage/database/msg.go @@ -0,0 +1,48 @@ +// 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 database + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" + "github.com/openimsdk/protocol/msg" + "go.mongodb.org/mongo-driver/mongo" + "time" +) + +type Msg interface { + PushMsgsToDoc(ctx context.Context, docID string, msgsToMongo []model.MsgInfoModel) error + Create(ctx context.Context, model *model.MsgDocModel) error + UpdateMsg(ctx context.Context, docID string, index int64, key string, value any) (*mongo.UpdateResult, error) + PushUnique(ctx context.Context, docID string, index int64, key string, value any) (*mongo.UpdateResult, error) + UpdateMsgContent(ctx context.Context, docID string, index int64, msg []byte) error + IsExistDocID(ctx context.Context, docID string) (bool, error) + FindOneByDocID(ctx context.Context, docID string) (*model.MsgDocModel, error) + GetMsgBySeqIndexIn1Doc(ctx context.Context, userID, docID string, seqs []int64) ([]*model.MsgInfoModel, error) + GetNewestMsg(ctx context.Context, conversationID string) (*model.MsgInfoModel, error) + GetOldestMsg(ctx context.Context, conversationID string) (*model.MsgInfoModel, error) + DeleteDocs(ctx context.Context, docIDs []string) error + GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*model.MsgDocModel, error) + DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error + MarkSingleChatMsgsAsRead(ctx context.Context, userID string, docID string, indexes []int64) error + SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*model.MsgInfoModel, error) + RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*model.UserCount, dateCount map[string]int64, err error) + RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*model.GroupCount, dateCount map[string]int64, err error) + ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) + + DeleteDoc(ctx context.Context, docID string) error + DeleteMsgByIndex(ctx context.Context, docID string, index []int) error + GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*model.MsgDocModel, error) +} diff --git a/pkg/common/storage/database/object.go b/pkg/common/storage/database/object.go new file mode 100644 index 000000000..554f71f35 --- /dev/null +++ b/pkg/common/storage/database/object.go @@ -0,0 +1,26 @@ +// 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 database + +import ( + "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" +) + +type ObjectInfo interface { + SetObject(ctx context.Context, obj *model.Object) error + Take(ctx context.Context, engine string, name string) (*model.Object, error) + Delete(ctx context.Context, engine string, name string) error +} diff --git a/pkg/common/db/table/relation/subscribe.go b/pkg/common/storage/database/subscribe.go similarity index 74% rename from pkg/common/db/table/relation/subscribe.go rename to pkg/common/storage/database/subscribe.go index 4e184cf38..5905ecd07 100644 --- a/pkg/common/db/table/relation/subscribe.go +++ b/pkg/common/storage/database/subscribe.go @@ -12,27 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import "context" -// SubscribeUser collection constant. -const ( - SubscribeUser = "subscribe_user" -) - -// SubscribeUserModel collection structure. -type SubscribeUserModel struct { - UserID string `bson:"user_id" json:"userID"` - UserIDList []string `bson:"user_id_list" json:"userIDList"` -} - -func (SubscribeUserModel) TableName() string { - return SubscribeUser -} - -// SubscribeUserModelInterface Operation interface of user mongodb. -type SubscribeUserModelInterface interface { +// SubscribeUser Operation interface of user mongodb. +type SubscribeUser interface { // AddSubscriptionList Subscriber's handling of thresholds. AddSubscriptionList(ctx context.Context, userID string, userIDList []string) error // UnsubscriptionList Handling of unsubscribe. diff --git a/pkg/common/db/table/relation/user.go b/pkg/common/storage/database/user.go similarity index 63% rename from pkg/common/db/table/relation/user.go rename to pkg/common/storage/database/user.go index 938a8a77d..2e4088620 100644 --- a/pkg/common/db/table/relation/user.go +++ b/pkg/common/storage/database/user.go @@ -12,52 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package database import ( "context" - "time" - + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model" "github.com/openimsdk/protocol/user" "github.com/openimsdk/tools/db/pagination" + "time" ) -type UserModel struct { - UserID string `bson:"user_id"` - Nickname string `bson:"nickname"` - FaceURL string `bson:"face_url"` - Ex string `bson:"ex"` - AppMangerLevel int32 `bson:"app_manger_level"` - GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"` - CreateTime time.Time `bson:"create_time"` -} - -func (u *UserModel) GetNickname() string { - return u.Nickname -} - -func (u *UserModel) GetFaceURL() string { - return u.FaceURL -} - -func (u UserModel) GetUserID() string { - return u.UserID -} - -func (u UserModel) GetEx() string { - return u.Ex -} - -type UserModelInterface interface { - Create(ctx context.Context, users []*UserModel) (err error) +type User interface { + Create(ctx context.Context, users []*model.User) (err error) UpdateByMap(ctx context.Context, userID string, args map[string]any) (err error) - Find(ctx context.Context, userIDs []string) (users []*UserModel, err error) - Take(ctx context.Context, userID string) (user *UserModel, err error) - TakeNotification(ctx context.Context, level int64) (user []*UserModel, err error) - TakeByNickname(ctx context.Context, nickname string) (user []*UserModel, err error) - Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*UserModel, err error) - PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*UserModel, err error) - PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*UserModel, err error) + Find(ctx context.Context, userIDs []string) (users []*model.User, err error) + Take(ctx context.Context, userID string) (user *model.User, err error) + TakeNotification(ctx context.Context, level int64) (user []*model.User, err error) + TakeByNickname(ctx context.Context, nickname string) (user []*model.User, err error) + Page(ctx context.Context, pagination pagination.Pagination) (count int64, users []*model.User, err error) + PageFindUser(ctx context.Context, level1 int64, level2 int64, pagination pagination.Pagination) (count int64, users []*model.User, err error) + PageFindUserWithKeyword(ctx context.Context, level1 int64, level2 int64, userID, nickName string, pagination pagination.Pagination) (count int64, users []*model.User, err error) Exist(ctx context.Context, userID string) (exist bool, err error) GetAllUserID(ctx context.Context, pagination pagination.Pagination) (count int64, userIDs []string, err error) GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error) diff --git a/pkg/common/storage/model/black.go b/pkg/common/storage/model/black.go new file mode 100644 index 000000000..5e60a2fc3 --- /dev/null +++ b/pkg/common/storage/model/black.go @@ -0,0 +1,28 @@ +// 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 model + +import ( + "time" +) + +type Black struct { + OwnerUserID string `bson:"owner_user_id"` + BlockUserID string `bson:"block_user_id"` + CreateTime time.Time `bson:"create_time"` + AddSource int32 `bson:"add_source"` + OperatorUserID string `bson:"operator_user_id"` + Ex string `bson:"ex"` +} diff --git a/pkg/common/storage/model/conversation.go b/pkg/common/storage/model/conversation.go new file mode 100644 index 000000000..590899b3f --- /dev/null +++ b/pkg/common/storage/model/conversation.go @@ -0,0 +1,40 @@ +// 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 model + +import ( + "time" +) + +type Conversation struct { + OwnerUserID string `bson:"owner_user_id"` + ConversationID string `bson:"conversation_id"` + ConversationType int32 `bson:"conversation_type"` + UserID string `bson:"user_id"` + GroupID string `bson:"group_id"` + RecvMsgOpt int32 `bson:"recv_msg_opt"` + IsPinned bool `bson:"is_pinned"` + IsPrivateChat bool `bson:"is_private_chat"` + BurnDuration int32 `bson:"burn_duration"` + GroupAtType int32 `bson:"group_at_type"` + AttachedInfo string `bson:"attached_info"` + Ex string `bson:"ex"` + MaxSeq int64 `bson:"max_seq"` + MinSeq int64 `bson:"min_seq"` + CreateTime time.Time `bson:"create_time"` + IsMsgDestruct bool `bson:"is_msg_destruct"` + MsgDestructTime int64 `bson:"msg_destruct_time"` + LatestMsgDestructTime time.Time `bson:"latest_msg_destruct_time"` +} diff --git a/pkg/common/storage/model/doc.go b/pkg/common/storage/model/doc.go new file mode 100644 index 000000000..5eb7b36b0 --- /dev/null +++ b/pkg/common/storage/model/doc.go @@ -0,0 +1,15 @@ +// Copyright © 2024 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 model // import "github.com/openimsdk/open-im-server/v3/pkg/common/storage/model/relation" diff --git a/pkg/common/storage/model/friend.go b/pkg/common/storage/model/friend.go new file mode 100644 index 000000000..60a40d9c2 --- /dev/null +++ b/pkg/common/storage/model/friend.go @@ -0,0 +1,31 @@ +// 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 model + +import ( + "time" +) + +// Friend represents the data structure for a friend relationship in MongoDB. +type Friend struct { + OwnerUserID string `bson:"owner_user_id"` + FriendUserID string `bson:"friend_user_id"` + Remark string `bson:"remark"` + CreateTime time.Time `bson:"create_time"` + AddSource int32 `bson:"add_source"` + OperatorUserID string `bson:"operator_user_id"` + Ex string `bson:"ex"` + IsPinned bool `bson:"is_pinned"` +} diff --git a/pkg/common/storage/model/friend_request.go b/pkg/common/storage/model/friend_request.go new file mode 100644 index 000000000..7835690cb --- /dev/null +++ b/pkg/common/storage/model/friend_request.go @@ -0,0 +1,31 @@ +// 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 model + +import ( + "time" +) + +type FriendRequest struct { + FromUserID string `bson:"from_user_id"` + ToUserID string `bson:"to_user_id"` + HandleResult int32 `bson:"handle_result"` + ReqMsg string `bson:"req_msg"` + CreateTime time.Time `bson:"create_time"` + HandlerUserID string `bson:"handler_user_id"` + HandleMsg string `bson:"handle_msg"` + HandleTime time.Time `bson:"handle_time"` + Ex string `bson:"ex"` +} diff --git a/pkg/common/db/table/relation/group.go b/pkg/common/storage/model/group.go similarity index 62% rename from pkg/common/db/table/relation/group.go rename to pkg/common/storage/model/group.go index f479a4745..714fcc782 100644 --- a/pkg/common/db/table/relation/group.go +++ b/pkg/common/storage/model/group.go @@ -12,16 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package model import ( - "context" "time" - - "github.com/openimsdk/tools/db/pagination" ) -type GroupModel struct { +type Group struct { GroupID string `bson:"group_id"` GroupName string `bson:"group_name"` Notification string `bson:"notification"` @@ -38,16 +35,3 @@ type GroupModel struct { NotificationUpdateTime time.Time `bson:"notification_update_time"` NotificationUserID string `bson:"notification_user_id"` } - -type GroupModelInterface interface { - Create(ctx context.Context, groups []*GroupModel) (err error) - UpdateMap(ctx context.Context, groupID string, args map[string]any) (err error) - UpdateStatus(ctx context.Context, groupID string, status int32) (err error) - Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error) - Take(ctx context.Context, groupID string) (group *GroupModel, err error) - Search(ctx context.Context, keyword string, pagination pagination.Pagination) (total int64, groups []*GroupModel, err error) - // Get Group total quantity - CountTotal(ctx context.Context, before *time.Time) (count int64, err error) - // Get Group total quantity every day - CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) -} diff --git a/pkg/common/storage/model/group_member.go b/pkg/common/storage/model/group_member.go new file mode 100644 index 000000000..4cb0703ed --- /dev/null +++ b/pkg/common/storage/model/group_member.go @@ -0,0 +1,33 @@ +// 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 model + +import ( + "time" +) + +type GroupMember struct { + GroupID string `bson:"group_id"` + UserID string `bson:"user_id"` + Nickname string `bson:"nickname"` + FaceURL string `bson:"face_url"` + RoleLevel int32 `bson:"role_level"` + JoinTime time.Time `bson:"join_time"` + JoinSource int32 `bson:"join_source"` + InviterUserID string `bson:"inviter_user_id"` + OperatorUserID string `bson:"operator_user_id"` + MuteEndTime time.Time `bson:"mute_end_time"` + Ex string `bson:"ex"` +} diff --git a/pkg/common/storage/model/group_request.go b/pkg/common/storage/model/group_request.go new file mode 100644 index 000000000..d075699f1 --- /dev/null +++ b/pkg/common/storage/model/group_request.go @@ -0,0 +1,33 @@ +// 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 model + +import ( + "time" +) + +type GroupRequest struct { + UserID string `bson:"user_id"` + GroupID string `bson:"group_id"` + HandleResult int32 `bson:"handle_result"` + ReqMsg string `bson:"req_msg"` + HandledMsg string `bson:"handled_msg"` + ReqTime time.Time `bson:"req_time"` + HandleUserID string `bson:"handle_user_id"` + HandledTime time.Time `bson:"handled_time"` + JoinSource int32 `bson:"join_source"` + InviterUserID string `bson:"inviter_user_id"` + Ex string `bson:"ex"` +} diff --git a/pkg/common/db/table/relation/log.go b/pkg/common/storage/model/log.go similarity index 67% rename from pkg/common/db/table/relation/log.go rename to pkg/common/storage/model/log.go index afc32c68e..9db72c695 100644 --- a/pkg/common/db/table/relation/log.go +++ b/pkg/common/storage/model/log.go @@ -12,16 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package model import ( - "context" "time" - - "github.com/openimsdk/tools/db/pagination" ) -type LogModel struct { +type Log struct { LogID string `bson:"log_id"` Platform string `bson:"platform"` UserID string `bson:"user_id"` @@ -32,10 +29,3 @@ type LogModel struct { Version string `bson:"version"` Ex string `bson:"ex"` } - -type LogInterface interface { - Create(ctx context.Context, log []*LogModel) error - Search(ctx context.Context, keyword string, start time.Time, end time.Time, pagination pagination.Pagination) (int64, []*LogModel, error) - Delete(ctx context.Context, logID []string, userID string) error - Get(ctx context.Context, logIDs []string, userID string) ([]*LogModel, error) -} diff --git a/pkg/common/db/table/relation/msg.go b/pkg/common/storage/model/msg.go similarity index 65% rename from pkg/common/db/table/relation/msg.go rename to pkg/common/storage/model/msg.go index 41a6ede97..8095665d2 100644 --- a/pkg/common/db/table/relation/msg.go +++ b/pkg/common/storage/model/msg.go @@ -12,23 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package model import ( - "context" - "strconv" - "time" - - "github.com/openimsdk/protocol/msg" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/errs" - "go.mongodb.org/mongo-driver/mongo" + "strconv" ) const ( singleGocMsgNum = 100 singleGocMsgNum5000 = 5000 - Msg = "msg" + MsgTableName = "msg" OldestList = 0 NewestList = -1 ) @@ -97,35 +92,8 @@ type GroupCount struct { Count int64 `bson:"count"` } -type MsgDocModelInterface interface { - PushMsgsToDoc(ctx context.Context, docID string, msgsToMongo []MsgInfoModel) error - Create(ctx context.Context, model *MsgDocModel) error - UpdateMsg(ctx context.Context, docID string, index int64, key string, value any) (*mongo.UpdateResult, error) - PushUnique(ctx context.Context, docID string, index int64, key string, value any) (*mongo.UpdateResult, error) - UpdateMsgContent(ctx context.Context, docID string, index int64, msg []byte) error - IsExistDocID(ctx context.Context, docID string) (bool, error) - FindOneByDocID(ctx context.Context, docID string) (*MsgDocModel, error) - GetMsgBySeqIndexIn1Doc(ctx context.Context, userID, docID string, seqs []int64) ([]*MsgInfoModel, error) - GetNewestMsg(ctx context.Context, conversationID string) (*MsgInfoModel, error) - GetOldestMsg(ctx context.Context, conversationID string) (*MsgInfoModel, error) - DeleteDocs(ctx context.Context, docIDs []string) error - GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*MsgDocModel, error) - DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error - MarkSingleChatMsgsAsRead(ctx context.Context, userID string, docID string, indexes []int64) error - SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (int32, []*MsgInfoModel, error) - RangeUserSendCount(ctx context.Context, start time.Time, end time.Time, group bool, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, users []*UserCount, dateCount map[string]int64, err error) - RangeGroupSendCount(ctx context.Context, start time.Time, end time.Time, ase bool, pageNumber int32, showNumber int32) (msgCount int64, userCount int64, groups []*GroupCount, dateCount map[string]int64, err error) - ConvertMsgsDocLen(ctx context.Context, conversationIDs []string) - - DeleteDoc(ctx context.Context, docID string) error - DeleteMsgByIndex(ctx context.Context, docID string, index []int) error - GetBeforeMsg(ctx context.Context, ts int64, limit int) ([]*MsgDocModel, error) - - //ClearMsg(ctx context.Context, t time.Time) (int64, error) -} - func (MsgDocModel) TableName() string { - return Msg + return MsgTableName } func (MsgDocModel) GetSingleGocMsgNum() int64 { diff --git a/pkg/common/db/table/relation/object.go b/pkg/common/storage/model/object.go similarity index 76% rename from pkg/common/db/table/relation/object.go rename to pkg/common/storage/model/object.go index 678fddcfd..e08a55d73 100644 --- a/pkg/common/db/table/relation/object.go +++ b/pkg/common/storage/model/object.go @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package relation +package model import ( - "context" "time" ) -type ObjectModel struct { +type Object struct { Name string `bson:"name"` UserID string `bson:"user_id"` Hash string `bson:"hash"` @@ -30,9 +29,3 @@ type ObjectModel struct { Group string `bson:"group"` CreateTime time.Time `bson:"create_time"` } - -type ObjectInfoModelInterface interface { - SetObject(ctx context.Context, obj *ObjectModel) error - Take(ctx context.Context, engine string, name string) (*ObjectModel, error) - Delete(ctx context.Context, engine string, name string) error -} diff --git a/pkg/common/storage/model/subscribe.go b/pkg/common/storage/model/subscribe.go new file mode 100644 index 000000000..e71fef3e9 --- /dev/null +++ b/pkg/common/storage/model/subscribe.go @@ -0,0 +1,30 @@ +// 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 model + +// SubscribeUserTableName collection constant. +const ( + SubscribeUserTableName = "subscribe_user" +) + +// SubscribeUser collection structure. +type SubscribeUser struct { + UserID string `bson:"user_id" json:"userID"` + UserIDList []string `bson:"user_id_list" json:"userIDList"` +} + +func (SubscribeUser) TableName() string { + return SubscribeUserTableName +} diff --git a/pkg/common/storage/model/user.go b/pkg/common/storage/model/user.go new file mode 100644 index 000000000..c6a4f952c --- /dev/null +++ b/pkg/common/storage/model/user.go @@ -0,0 +1,45 @@ +// Copyright © 2023 OpenIM. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package model + +import ( + "time" +) + +type User struct { + UserID string `bson:"user_id"` + Nickname string `bson:"nickname"` + FaceURL string `bson:"face_url"` + Ex string `bson:"ex"` + AppMangerLevel int32 `bson:"app_manger_level"` + GlobalRecvMsgOpt int32 `bson:"global_recv_msg_opt"` + CreateTime time.Time `bson:"create_time"` +} + +func (u *User) GetNickname() string { + return u.Nickname +} + +func (u *User) GetFaceURL() string { + return u.FaceURL +} + +func (u User) GetUserID() string { + return u.UserID +} + +func (u User) GetEx() string { + return u.Ex +} diff --git a/pkg/common/db/cache/config.go b/pkg/localcache/init.go similarity index 73% rename from pkg/common/db/cache/config.go rename to pkg/localcache/init.go index bb5bd449b..d1c16f675 100644 --- a/pkg/common/db/cache/config.go +++ b/pkg/localcache/init.go @@ -12,14 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -package cache +package localcache import ( + "github.com/openimsdk/open-im-server/v3/pkg/common/config" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" "strings" "sync" - - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" - "github.com/openimsdk/open-im-server/v3/pkg/common/config" ) var ( @@ -59,26 +58,26 @@ func InitLocalCache(localCache *config.LocalCache) { }) } -func getPublishKey(topic string, key []string) []string { - if topic == "" || len(key) == 0 { - return nil - } - prefix, ok := subscribe[topic] - if !ok { - return nil +func GetPublishKeysByTopic(topics []string, keys []string) map[string][]string { + keysByTopic := make(map[string][]string) + for _, topic := range topics { + keysByTopic[topic] = []string{} } - res := make([]string, 0, len(key)) - for _, k := range key { - var exist bool - for _, p := range prefix { - if strings.HasPrefix(k, p) { - exist = true - break + + for _, key := range keys { + for _, topic := range topics { + prefixes, ok := subscribe[topic] + if !ok { + continue + } + for _, prefix := range prefixes { + if strings.HasPrefix(key, prefix) { + keysByTopic[topic] = append(keysByTopic[topic], key) + break + } } - } - if exist { - res = append(res, k) } } - return res + + return keysByTopic } diff --git a/pkg/rpccache/conversation.go b/pkg/rpccache/conversation.go index 55897a8da..4c00dd1f7 100644 --- a/pkg/rpccache/conversation.go +++ b/pkg/rpccache/conversation.go @@ -16,8 +16,8 @@ package rpccache import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" diff --git a/pkg/rpccache/friend.go b/pkg/rpccache/friend.go index 3e9e7863a..a5cee2567 100644 --- a/pkg/rpccache/friend.go +++ b/pkg/rpccache/friend.go @@ -16,8 +16,8 @@ package rpccache import ( "context" + cachekey2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" @@ -58,10 +58,10 @@ func (f *FriendLocalCache) IsFriend(ctx context.Context, possibleFriendUserID, u log.ZError(ctx, "FriendLocalCache IsFriend return", err) } }() - return localcache.AnyValue[bool](f.local.GetLink(ctx, cachekey.GetIsFriendKey(possibleFriendUserID, userID), func(ctx context.Context) (any, error) { + return localcache.AnyValue[bool](f.local.GetLink(ctx, cachekey2.GetIsFriendKey(possibleFriendUserID, userID), func(ctx context.Context) (any, error) { log.ZDebug(ctx, "FriendLocalCache IsFriend rpc", "possibleFriendUserID", possibleFriendUserID, "userID", userID) return f.client.IsFriend(ctx, possibleFriendUserID, userID) - }, cachekey.GetFriendIDsKey(possibleFriendUserID))) + }, cachekey2.GetFriendIDsKey(possibleFriendUserID))) } // IsBlack possibleBlackUserID selfUserID. @@ -74,8 +74,8 @@ func (f *FriendLocalCache) IsBlack(ctx context.Context, possibleBlackUserID, use log.ZError(ctx, "FriendLocalCache IsBlack return", err) } }() - return localcache.AnyValue[bool](f.local.GetLink(ctx, cachekey.GetIsBlackIDsKey(possibleBlackUserID, userID), func(ctx context.Context) (any, error) { + return localcache.AnyValue[bool](f.local.GetLink(ctx, cachekey2.GetIsBlackIDsKey(possibleBlackUserID, userID), func(ctx context.Context) (any, error) { log.ZDebug(ctx, "FriendLocalCache IsBlack rpc", "possibleBlackUserID", possibleBlackUserID, "userID", userID) return f.client.IsBlack(ctx, possibleBlackUserID, userID) - }, cachekey.GetBlackIDsKey(userID))) + }, cachekey2.GetBlackIDsKey(userID))) } diff --git a/pkg/rpccache/group.go b/pkg/rpccache/group.go index 7ba22beb8..55e1438be 100644 --- a/pkg/rpccache/group.go +++ b/pkg/rpccache/group.go @@ -16,8 +16,8 @@ package rpccache import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" diff --git a/pkg/rpccache/user.go b/pkg/rpccache/user.go index 0a7a4e4b8..25a8eb20d 100644 --- a/pkg/rpccache/user.go +++ b/pkg/rpccache/user.go @@ -16,8 +16,8 @@ package rpccache import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/cachekey" - "github.com/openimsdk/open-im-server/v3/pkg/common/cachekey" "github.com/openimsdk/open-im-server/v3/pkg/common/config" "github.com/openimsdk/open-im-server/v3/pkg/localcache" "github.com/openimsdk/open-im-server/v3/pkg/rpcclient" diff --git a/test/testdata/README.md b/test/testdata/README.md index 74cdb71f8..b9dfea676 100644 --- a/test/testdata/README.md +++ b/test/testdata/README.md @@ -10,7 +10,7 @@ testdata/ │ ├── README.md # 描述该目录下各子目录和文件的作用 │ -├── db/ # 存储模拟的数据库数据 +├── storage/ # 存储模拟的数据库数据 │ ├── users.json # 用户的模拟数据 │ └── messages.json # 消息的模拟数据 │