feat: Remove MySQL and implement it all with Mongo (#1508)
* fix: GetUserReqApplicationList error when there is a disbanded group chat
* fix: error when querying some information about disbanded group
* fix: GetUserReqApplicationList dismissed group error
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* fix: the original message referenced by the pull message processing is withdrawn
* merge
* cicd: robot automated Change
* sdkws.MsgData
* user
* interface{} -> any
* user
* third
* group
* group
* group
* group
* group
* group
* conversation
* standalone mysql db model
* tx
* s3
* group
* mongo
* group
* group
* group
* group
* group
* group
* refactor: add openim mysql to mongo refactor
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* refactor: add openim mysql to mongo refactor
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* remove mysql
* remove mysql
* friend
* friend
* friend
* friend
* friend
* friend
* group
* convert
* index
* index
* all
* all
* mysql2mongo
* data conversion
* up35
* up35
* feat: add format set
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* fix: fix scripts
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
* merge main
* merge main
* Update init-config.sh
* fix: user args check
---------
Signed-off-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
Co-authored-by: withchao <withchao@users.noreply.github.com>
Co-authored-by: Xinwei Xiong(cubxxw) <3293172751nss@gmail.com>
Co-authored-by: Xinwei Xiong <3293172751@qq.com>
This commit is contained in:
@@ -84,7 +84,7 @@ func main() {
|
||||
}
|
||||
|
||||
checks := []checkFunc{
|
||||
{name: "Mysql", function: checkMysql},
|
||||
//{name: "Mysql", function: checkMysql},
|
||||
{name: "Mongo", function: checkMongo},
|
||||
{name: "Minio", function: checkMinio},
|
||||
{name: "Redis", function: checkRedis},
|
||||
@@ -133,6 +133,9 @@ func exactIP(urll string) string {
|
||||
}
|
||||
|
||||
func checkMysql() error {
|
||||
if config.Config.Mysql == nil {
|
||||
return nil
|
||||
}
|
||||
var sqlDB *sql.DB
|
||||
defer func() {
|
||||
if sqlDB != nil {
|
||||
|
||||
@@ -15,8 +15,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
@@ -40,3 +44,43 @@ func mockInitCfg() error {
|
||||
config.Config.Mysql.Address = []string{"127.0.0.1:13306"}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestRedis(t *testing.T) {
|
||||
config.Config.Redis.Address = []string{
|
||||
"172.16.8.142:7000",
|
||||
//"172.16.8.142:7000", "172.16.8.142:7001", "172.16.8.142:7002", "172.16.8.142:7003", "172.16.8.142:7004", "172.16.8.142:7005",
|
||||
}
|
||||
|
||||
var redisClient redis.UniversalClient
|
||||
defer func() {
|
||||
if redisClient != nil {
|
||||
redisClient.Close()
|
||||
}
|
||||
}()
|
||||
if len(config.Config.Redis.Address) > 1 {
|
||||
redisClient = redis.NewClusterClient(&redis.ClusterOptions{
|
||||
Addrs: config.Config.Redis.Address,
|
||||
Username: config.Config.Redis.Username,
|
||||
Password: config.Config.Redis.Password,
|
||||
})
|
||||
} else {
|
||||
redisClient = redis.NewClient(&redis.Options{
|
||||
Addr: config.Config.Redis.Address[0],
|
||||
Username: config.Config.Redis.Username,
|
||||
Password: config.Config.Redis.Password,
|
||||
})
|
||||
}
|
||||
_, err := redisClient.Ping(context.Background()).Result()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 1000000; i++ {
|
||||
val, err := redisClient.Set(context.Background(), "b_"+strconv.Itoa(i), "test", time.Second*10).Result()
|
||||
t.Log("index", i, "resp", val, "err", err)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
### 2. 迁移 OpenIM MySQL 数据
|
||||
|
||||
+ 位置: `open-im-server/v3/tools/data-conversion/openim/mysql.go`
|
||||
+ 配置 `mysql.go` 文件中的数据库信息。
|
||||
+ 位置: `open-im-server/tools/data-conversion/openim/cmd/conversion-mysql.go`
|
||||
+ 配置 `conversion-mysql.go` 文件中的数据库信息。
|
||||
+ 手动创建 V3 版本的数据库,并确保字符集为 `utf8mb4`。
|
||||
|
||||
```bash
|
||||
@@ -47,7 +47,7 @@ make build BINS="conversion-mysql"
|
||||
### 3. 转换聊天消息(可选)
|
||||
|
||||
+ 只支持转换存储在 Kafka 中的消息。
|
||||
+ 位置: `open-im-server/v3/tools/data-conversion/openim/msg.go`
|
||||
+ 位置: `open-im-server/tools/data-conversion/openim/conversion-msg/conversion-msg.go`
|
||||
+ 配置 `msg.go` 文件中的消息和服务器信息。
|
||||
|
||||
```bash
|
||||
@@ -69,7 +69,7 @@ make build BINS="conversion-msg"
|
||||
### 4. 转换业务服务器数据
|
||||
|
||||
+ 只支持转换存储在 Kafka 中的消息。
|
||||
+ 位置: `open-im-server/v3/tools/data-conversion/chat/chat.go`
|
||||
+ 位置: `open-im-server/tools/data-conversion/chat/cmd/conversion-chat/chat.go`
|
||||
+ 需要手动创建 V3 版本的数据库,并确保字符集为 `utf8mb4`。
|
||||
+ 配置 `main.go` 文件中的数据库信息。
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ package conversion
|
||||
import (
|
||||
"github.com/OpenIMSDK/protocol/constant"
|
||||
|
||||
v3 "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
v2 "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v2"
|
||||
v3 "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3"
|
||||
"github.com/openimsdk/open-im-server/v3/tools/data-conversion/utils"
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
BlackModelTableName = "blacks"
|
||||
)
|
||||
|
||||
type BlackModel struct {
|
||||
OwnerUserID string `gorm:"column:owner_user_id;primary_key;size:64"`
|
||||
BlockUserID string `gorm:"column:block_user_id;primary_key;size:64"`
|
||||
CreateTime time.Time `gorm:"column:create_time"`
|
||||
AddSource int32 `gorm:"column:add_source"`
|
||||
OperatorUserID string `gorm:"column:operator_user_id;size:64"`
|
||||
Ex string `gorm:"column:ex;size:1024"`
|
||||
}
|
||||
|
||||
func (BlackModel) TableName() string {
|
||||
return BlackModelTableName
|
||||
}
|
||||
|
||||
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]interface{}) (err error)
|
||||
Update(ctx context.Context, blacks []*BlackModel) (err error)
|
||||
Find(ctx context.Context, blacks []*BlackModel) (blackList []*BlackModel, err error)
|
||||
Take(ctx context.Context, ownerUserID, blockUserID string) (black *BlackModel, err error)
|
||||
FindOwnerBlacks(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (blacks []*BlackModel, total int64, err error)
|
||||
FindOwnerBlackInfos(ctx context.Context, ownerUserID string, userIDs []string) (blacks []*BlackModel, err error)
|
||||
FindBlackUserIDs(ctx context.Context, ownerUserID string) (blackUserIDs []string, err error)
|
||||
}
|
||||
@@ -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 relation
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
pbmsg "github.com/OpenIMSDK/protocol/msg"
|
||||
)
|
||||
|
||||
const (
|
||||
ChatLogModelTableName = "chat_logs"
|
||||
)
|
||||
|
||||
type ChatLogModel struct {
|
||||
ServerMsgID string `gorm:"column:server_msg_id;primary_key;type:char(64)" json:"serverMsgID"`
|
||||
ClientMsgID string `gorm:"column:client_msg_id;type:char(64)" json:"clientMsgID"`
|
||||
SendID string `gorm:"column:send_id;type:char(64);index:send_id,priority:2" json:"sendID"`
|
||||
RecvID string `gorm:"column:recv_id;type:char(64);index:recv_id,priority:2" json:"recvID"`
|
||||
SenderPlatformID int32 `gorm:"column:sender_platform_id" json:"senderPlatformID"`
|
||||
SenderNickname string `gorm:"column:sender_nick_name;type:varchar(255)" json:"senderNickname"`
|
||||
SenderFaceURL string `gorm:"column:sender_face_url;type:varchar(255);" json:"senderFaceURL"`
|
||||
SessionType int32 `gorm:"column:session_type;index:session_type,priority:2;index:session_type_alone" json:"sessionType"`
|
||||
MsgFrom int32 `gorm:"column:msg_from" json:"msgFrom"`
|
||||
ContentType int32 `gorm:"column:content_type;index:content_type,priority:2;index:content_type_alone" json:"contentType"`
|
||||
Content string `gorm:"column:content;type:varchar(3000)" json:"content"`
|
||||
Status int32 `gorm:"column:status" json:"status"`
|
||||
SendTime time.Time `gorm:"column:send_time;index:sendTime;index:content_type,priority:1;index:session_type,priority:1;index:recv_id,priority:1;index:send_id,priority:1" json:"sendTime"`
|
||||
CreateTime time.Time `gorm:"column:create_time" json:"createTime"`
|
||||
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
|
||||
}
|
||||
|
||||
func (ChatLogModel) TableName() string {
|
||||
return ChatLogModelTableName
|
||||
}
|
||||
|
||||
type ChatLogModelInterface interface {
|
||||
Create(msg *pbmsg.MsgDataToMQ) error
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
conversationModelTableName = "conversations"
|
||||
)
|
||||
|
||||
type ConversationModel struct {
|
||||
OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:char(128)" json:"OwnerUserID"`
|
||||
ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"`
|
||||
ConversationType int32 `gorm:"column:conversation_type" json:"conversationType"`
|
||||
UserID string `gorm:"column:user_id;type:char(64)" json:"userID"`
|
||||
GroupID string `gorm:"column:group_id;type:char(128)" json:"groupID"`
|
||||
RecvMsgOpt int32 `gorm:"column:recv_msg_opt" json:"recvMsgOpt"`
|
||||
IsPinned bool `gorm:"column:is_pinned" json:"isPinned"`
|
||||
IsPrivateChat bool `gorm:"column:is_private_chat" json:"isPrivateChat"`
|
||||
BurnDuration int32 `gorm:"column:burn_duration;default:30" json:"burnDuration"`
|
||||
GroupAtType int32 `gorm:"column:group_at_type" json:"groupAtType"`
|
||||
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
|
||||
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
|
||||
MaxSeq int64 `gorm:"column:max_seq" json:"maxSeq"`
|
||||
MinSeq int64 `gorm:"column:min_seq" json:"minSeq"`
|
||||
CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"`
|
||||
IsMsgDestruct bool `gorm:"column:is_msg_destruct;default:false"`
|
||||
MsgDestructTime int64 `gorm:"column:msg_destruct_time;default:604800"`
|
||||
LatestMsgDestructTime time.Time `gorm:"column:latest_msg_destruct_time;autoCreateTime"`
|
||||
}
|
||||
|
||||
func (ConversationModel) TableName() string {
|
||||
return conversationModelTableName
|
||||
}
|
||||
|
||||
type ConversationModelInterface interface {
|
||||
Create(ctx context.Context, conversations []*ConversationModel) (err error)
|
||||
Delete(ctx context.Context, groupIDs []string) (err error)
|
||||
UpdateByMap(ctx context.Context, userIDs []string, conversationID string, args map[string]interface{}) (rows int64, err error)
|
||||
Update(ctx context.Context, conversation *ConversationModel) (err error)
|
||||
Find(ctx context.Context, ownerUserID string, conversationIDs []string) (conversations []*ConversationModel, 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)
|
||||
FindConversationID(ctx context.Context, userID string, conversationIDs []string) (existConversationID []string, err error)
|
||||
FindUserIDAllConversations(ctx context.Context, userID string) (conversations []*ConversationModel, err error)
|
||||
FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
|
||||
GetUserRecvMsgOpt(ctx context.Context, ownerUserID, conversationID string) (opt int, err error)
|
||||
FindSuperGroupRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error)
|
||||
GetAllConversationIDs(ctx context.Context) ([]string, error)
|
||||
GetAllConversationIDsNumber(ctx context.Context) (int64, error)
|
||||
PageConversationIDs(ctx context.Context, pageNumber, showNumber int32) (conversationIDs []string, err error)
|
||||
GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (hashReadSeqs map[string]int64, err error)
|
||||
GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*ConversationModel, error)
|
||||
GetConversationIDsNeedDestruct(ctx context.Context) ([]*ConversationModel, error)
|
||||
GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error)
|
||||
NewTx(tx any) ConversationModelInterface
|
||||
}
|
||||
@@ -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 relation // import "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
FriendModelTableName = "friends"
|
||||
)
|
||||
|
||||
type FriendModel struct {
|
||||
OwnerUserID string `gorm:"column:owner_user_id;primary_key;size:64"`
|
||||
FriendUserID string `gorm:"column:friend_user_id;primary_key;size:64"`
|
||||
Remark string `gorm:"column:remark;size:255"`
|
||||
CreateTime time.Time `gorm:"column:create_time;autoCreateTime"`
|
||||
AddSource int32 `gorm:"column:add_source"`
|
||||
OperatorUserID string `gorm:"column:operator_user_id;size:64"`
|
||||
Ex string `gorm:"column:ex;size:1024"`
|
||||
}
|
||||
|
||||
func (FriendModel) TableName() string {
|
||||
return FriendModelTableName
|
||||
}
|
||||
|
||||
type FriendModelInterface interface {
|
||||
// 插入多条记录
|
||||
Create(ctx context.Context, friends []*FriendModel) (err error)
|
||||
// 删除ownerUserID指定的好友
|
||||
Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error)
|
||||
// 更新ownerUserID单个好友信息 更新零值
|
||||
UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) (err error)
|
||||
// 更新好友信息的非零值
|
||||
Update(ctx context.Context, friends []*FriendModel) (err error)
|
||||
// 更新好友备注(也支持零值 )
|
||||
UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error)
|
||||
// 获取单个好友信息,如没找到 返回错误
|
||||
Take(ctx context.Context, ownerUserID, friendUserID string) (friend *FriendModel, err error)
|
||||
// 查找好友关系,如果是双向关系,则都返回
|
||||
FindUserState(ctx context.Context, userID1, userID2 string) (friends []*FriendModel, err error)
|
||||
// 获取 owner指定的好友列表 如果有friendUserIDs不存在,也不返回错误
|
||||
FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*FriendModel, err error)
|
||||
// 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在,也不返回错误
|
||||
FindReversalFriends(
|
||||
ctx context.Context,
|
||||
friendUserID string,
|
||||
ownerUserIDs []string,
|
||||
) (friends []*FriendModel, err error)
|
||||
// 获取ownerUserID好友列表 支持翻页
|
||||
FindOwnerFriends(
|
||||
ctx context.Context,
|
||||
ownerUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*FriendModel, total int64, err error)
|
||||
// 获取哪些人添加了friendUserID 支持翻页
|
||||
FindInWhoseFriends(
|
||||
ctx context.Context,
|
||||
friendUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friends []*FriendModel, total int64, err error)
|
||||
// 获取好友UserID列表
|
||||
FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error)
|
||||
NewTx(tx any) FriendModelInterface
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const FriendRequestModelTableName = "friend_requests"
|
||||
|
||||
type FriendRequestModel struct {
|
||||
FromUserID string `gorm:"column:from_user_id;primary_key;size:64"`
|
||||
ToUserID string `gorm:"column:to_user_id;primary_key;size:64"`
|
||||
HandleResult int32 `gorm:"column:handle_result"`
|
||||
ReqMsg string `gorm:"column:req_msg;size:255"`
|
||||
CreateTime time.Time `gorm:"column:create_time; autoCreateTime"`
|
||||
HandlerUserID string `gorm:"column:handler_user_id;size:64"`
|
||||
HandleMsg string `gorm:"column:handle_msg;size:255"`
|
||||
HandleTime time.Time `gorm:"column:handle_time"`
|
||||
Ex string `gorm:"column:ex;size:1024"`
|
||||
}
|
||||
|
||||
func (FriendRequestModel) TableName() string {
|
||||
return FriendRequestModelTableName
|
||||
}
|
||||
|
||||
type FriendRequestModelInterface interface {
|
||||
// 插入多条记录
|
||||
Create(ctx context.Context, friendRequests []*FriendRequestModel) (err error)
|
||||
// 删除记录
|
||||
Delete(ctx context.Context, fromUserID, toUserID string) (err error)
|
||||
// 更新零值
|
||||
UpdateByMap(ctx context.Context, formUserID string, toUserID string, args map[string]interface{}) (err error)
|
||||
// 更新多条记录 (非零值)
|
||||
Update(ctx context.Context, friendRequest *FriendRequestModel) (err error)
|
||||
// 获取来指定用户的好友申请 未找到 不返回错误
|
||||
Find(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error)
|
||||
Take(ctx context.Context, fromUserID, toUserID string) (friendRequest *FriendRequestModel, err error)
|
||||
// 获取toUserID收到的好友申请列表
|
||||
FindToUserID(
|
||||
ctx context.Context,
|
||||
toUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friendRequests []*FriendRequestModel, total int64, err error)
|
||||
// 获取fromUserID发出去的好友申请列表
|
||||
FindFromUserID(
|
||||
ctx context.Context,
|
||||
fromUserID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (friendRequests []*FriendRequestModel, total int64, err error)
|
||||
FindBothFriendRequests(ctx context.Context, fromUserID, toUserID string) (friends []*FriendRequestModel, err error)
|
||||
NewTx(tx any) FriendRequestModelInterface
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
GroupModelTableName = "groups"
|
||||
)
|
||||
|
||||
type GroupModel struct {
|
||||
GroupID string `gorm:"column:group_id;primary_key;size:64" json:"groupID" binding:"required"`
|
||||
GroupName string `gorm:"column:name;size:255" json:"groupName"`
|
||||
Notification string `gorm:"column:notification;size:255" json:"notification"`
|
||||
Introduction string `gorm:"column:introduction;size:255" json:"introduction"`
|
||||
FaceURL string `gorm:"column:face_url;size:255" json:"faceURL"`
|
||||
CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"`
|
||||
Ex string `gorm:"column:ex" json:"ex;size:1024"`
|
||||
Status int32 `gorm:"column:status"`
|
||||
CreatorUserID string `gorm:"column:creator_user_id;size:64"`
|
||||
GroupType int32 `gorm:"column:group_type"`
|
||||
NeedVerification int32 `gorm:"column:need_verification"`
|
||||
LookMemberInfo int32 `gorm:"column:look_member_info" json:"lookMemberInfo"`
|
||||
ApplyMemberFriend int32 `gorm:"column:apply_member_friend" json:"applyMemberFriend"`
|
||||
NotificationUpdateTime time.Time `gorm:"column:notification_update_time"`
|
||||
NotificationUserID string `gorm:"column:notification_user_id;size:64"`
|
||||
}
|
||||
|
||||
func (GroupModel) TableName() string {
|
||||
return GroupModelTableName
|
||||
}
|
||||
|
||||
type GroupModelInterface interface {
|
||||
NewTx(tx any) GroupModelInterface
|
||||
Create(ctx context.Context, groups []*GroupModel) (err error)
|
||||
UpdateMap(ctx context.Context, groupID string, args map[string]interface{}) (err error)
|
||||
UpdateStatus(ctx context.Context, groupID string, status int32) (err error)
|
||||
Find(ctx context.Context, groupIDs []string) (groups []*GroupModel, err error)
|
||||
FindNotDismissedGroup(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,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, groups []*GroupModel, err error)
|
||||
GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error)
|
||||
// 获取群总数
|
||||
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)
|
||||
// 获取范围内群增量
|
||||
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
GroupMemberModelTableName = "group_members"
|
||||
)
|
||||
|
||||
type GroupMemberModel struct {
|
||||
GroupID string `gorm:"column:group_id;primary_key;size:64"`
|
||||
UserID string `gorm:"column:user_id;primary_key;size:64"`
|
||||
Nickname string `gorm:"column:nickname;size:255"`
|
||||
FaceURL string `gorm:"column:user_group_face_url;size:255"`
|
||||
RoleLevel int32 `gorm:"column:role_level"`
|
||||
JoinTime time.Time `gorm:"column:join_time"`
|
||||
JoinSource int32 `gorm:"column:join_source"`
|
||||
InviterUserID string `gorm:"column:inviter_user_id;size:64"`
|
||||
OperatorUserID string `gorm:"column:operator_user_id;size:64"`
|
||||
MuteEndTime time.Time `gorm:"column:mute_end_time"`
|
||||
Ex string `gorm:"column:ex;size:1024"`
|
||||
}
|
||||
|
||||
func (GroupMemberModel) TableName() string {
|
||||
return GroupMemberModelTableName
|
||||
}
|
||||
|
||||
type GroupMemberModelInterface interface {
|
||||
NewTx(tx any) GroupMemberModelInterface
|
||||
Create(ctx context.Context, groupMembers []*GroupMemberModel) (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) (rowsAffected int64, err error)
|
||||
Find(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
userIDs []string,
|
||||
roleLevels []int32,
|
||||
) (groupMembers []*GroupMemberModel, err 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,
|
||||
groupIDs []string,
|
||||
userIDs []string,
|
||||
roleLevels []int32,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, groupList []*GroupMemberModel, err 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)
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
GroupRequestModelTableName = "group_requests"
|
||||
)
|
||||
|
||||
type GroupRequestModel struct {
|
||||
UserID string `gorm:"column:user_id;primary_key;size:64"`
|
||||
GroupID string `gorm:"column:group_id;primary_key;size:64"`
|
||||
HandleResult int32 `gorm:"column:handle_result"`
|
||||
ReqMsg string `gorm:"column:req_msg;size:1024"`
|
||||
HandledMsg string `gorm:"column:handle_msg;size:1024"`
|
||||
ReqTime time.Time `gorm:"column:req_time"`
|
||||
HandleUserID string `gorm:"column:handle_user_id;size:64"`
|
||||
HandledTime time.Time `gorm:"column:handle_time"`
|
||||
JoinSource int32 `gorm:"column:join_source"`
|
||||
InviterUserID string `gorm:"column:inviter_user_id;size:64"`
|
||||
Ex string `gorm:"column:ex;size:1024"`
|
||||
}
|
||||
|
||||
func (GroupRequestModel) TableName() string {
|
||||
return GroupRequestModelTableName
|
||||
}
|
||||
|
||||
type GroupRequestModelInterface interface {
|
||||
NewTx(tx any) GroupRequestModelInterface
|
||||
Create(ctx context.Context, groupRequests []*GroupRequestModel) (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) (int64, []*GroupRequestModel, error)
|
||||
Page(
|
||||
ctx context.Context,
|
||||
userID string,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, groups []*GroupRequestModel, err error)
|
||||
PageGroup(
|
||||
ctx context.Context,
|
||||
groupIDs []string,
|
||||
pageNumber, showNumber int32,
|
||||
) (total uint32, groups []*GroupRequestModel, err error)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Log struct {
|
||||
LogID string `gorm:"column:log_id;primary_key;type:char(64)"`
|
||||
Platform string `gorm:"column:platform;type:varchar(32)"`
|
||||
UserID string `gorm:"column:user_id;type:char(64)"`
|
||||
CreateTime time.Time `gorm:"index:,sort:desc"`
|
||||
Url string `gorm:"column:url;type varchar(255)"`
|
||||
FileName string `gorm:"column:filename;type varchar(255)"`
|
||||
SystemType string `gorm:"column:system_type;type varchar(255)"`
|
||||
Version string `gorm:"column:version;type varchar(255)"`
|
||||
Ex string `gorm:"column:ex;type varchar(255)"`
|
||||
}
|
||||
|
||||
func (Log) TableName() string {
|
||||
return "logs"
|
||||
}
|
||||
|
||||
type LogInterface interface {
|
||||
Create(ctx context.Context, log []*Log) error
|
||||
Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*Log, error)
|
||||
Delete(ctx context.Context, logID []string, userID string) error
|
||||
Get(ctx context.Context, logIDs []string, userID string) ([]*Log, error)
|
||||
}
|
||||
@@ -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 relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
ObjectInfoModelTableName = "object"
|
||||
)
|
||||
|
||||
type ObjectModel struct {
|
||||
Name string `gorm:"column:name;primary_key"`
|
||||
UserID string `gorm:"column:user_id"`
|
||||
Hash string `gorm:"column:hash"`
|
||||
Key string `gorm:"column:key"`
|
||||
Size int64 `gorm:"column:size"`
|
||||
ContentType string `gorm:"column:content_type"`
|
||||
Cause string `gorm:"column:cause"`
|
||||
CreateTime time.Time `gorm:"column:create_time"`
|
||||
}
|
||||
|
||||
func (ObjectModel) TableName() string {
|
||||
return ObjectInfoModelTableName
|
||||
}
|
||||
|
||||
type ObjectInfoModelInterface interface {
|
||||
NewTx(tx any) ObjectInfoModelInterface
|
||||
SetObject(ctx context.Context, obj *ObjectModel) error
|
||||
Take(ctx context.Context, name string) (*ObjectModel, error)
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
UserModelTableName = "users"
|
||||
)
|
||||
|
||||
type UserModel struct {
|
||||
UserID string `gorm:"column:user_id;primary_key;size:64"`
|
||||
Nickname string `gorm:"column:name;size:255"`
|
||||
FaceURL string `gorm:"column:face_url;size:255"`
|
||||
Ex string `gorm:"column:ex;size:1024"`
|
||||
CreateTime time.Time `gorm:"column:create_time;index:create_time;autoCreateTime"`
|
||||
AppMangerLevel int32 `gorm:"column:app_manger_level;default:1"`
|
||||
GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt"`
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (UserModel) TableName() string {
|
||||
return UserModelTableName
|
||||
}
|
||||
|
||||
type UserModelInterface interface {
|
||||
Create(ctx context.Context, users []*UserModel) (err error)
|
||||
UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error)
|
||||
Update(ctx context.Context, user *UserModel) (err error)
|
||||
// 获取指定用户信息 不存在,也不返回错误
|
||||
Find(ctx context.Context, userIDs []string) (users []*UserModel, err error)
|
||||
// 获取某个用户信息 不存在,则返回错误
|
||||
Take(ctx context.Context, userID string) (user *UserModel, err error)
|
||||
// 获取用户信息 不存在,不返回错误
|
||||
Page(ctx context.Context, pageNumber, showNumber int32) (users []*UserModel, count int64, err error)
|
||||
GetAllUserID(ctx context.Context, pageNumber, showNumber int32) (userIDs []string, err error)
|
||||
GetUserGlobalRecvMsgOpt(ctx context.Context, userID string) (opt int, err error)
|
||||
// 获取用户总数
|
||||
CountTotal(ctx context.Context, before *time.Time) (count int64, err error)
|
||||
// 获取范围内用户增量
|
||||
CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright © 2023 OpenIM. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package relation
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/OpenIMSDK/tools/utils"
|
||||
)
|
||||
|
||||
type BatchUpdateGroupMember struct {
|
||||
GroupID string
|
||||
UserID string
|
||||
Map map[string]any
|
||||
}
|
||||
|
||||
type GroupSimpleUserID struct {
|
||||
Hash uint64
|
||||
MemberNum uint32
|
||||
}
|
||||
|
||||
func IsNotFound(err error) bool {
|
||||
return utils.Unwrap(err) == gorm.ErrRecordNotFound
|
||||
}
|
||||
@@ -2703,7 +2703,7 @@ func RegisterMsgServer(s *grpc.Server, srv MsgServer) {
|
||||
s.RegisterService(&_Msg_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Msg_GetMaxAndMinSeq_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_GetMaxAndMinSeq_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(sdk_ws.GetMaxAndMinSeqReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2715,13 +2715,13 @@ func _Msg_GetMaxAndMinSeq_Handler(srv interface{}, ctx context.Context, dec func
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/GetMaxAndMinSeq",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).GetMaxAndMinSeq(ctx, req.(*sdk_ws.GetMaxAndMinSeqReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_PullMessageBySeqList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_PullMessageBySeqList_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(sdk_ws.PullMessageBySeqListReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2733,13 +2733,13 @@ func _Msg_PullMessageBySeqList_Handler(srv interface{}, ctx context.Context, dec
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/PullMessageBySeqList",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).PullMessageBySeqList(ctx, req.(*sdk_ws.PullMessageBySeqListReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_SendMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_SendMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(SendMsgReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2751,13 +2751,13 @@ func _Msg_SendMsg_Handler(srv interface{}, ctx context.Context, dec func(interfa
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/SendMsg",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).SendMsg(ctx, req.(*SendMsgReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_DelMsgList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_DelMsgList_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(sdk_ws.DelMsgListReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2769,13 +2769,13 @@ func _Msg_DelMsgList_Handler(srv interface{}, ctx context.Context, dec func(inte
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/DelMsgList",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).DelMsgList(ctx, req.(*sdk_ws.DelMsgListReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_DelSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_DelSuperGroupMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(DelSuperGroupMsgReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2787,13 +2787,13 @@ func _Msg_DelSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec fun
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/DelSuperGroupMsg",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).DelSuperGroupMsg(ctx, req.(*DelSuperGroupMsgReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_ClearMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_ClearMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(ClearMsgReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2805,13 +2805,13 @@ func _Msg_ClearMsg_Handler(srv interface{}, ctx context.Context, dec func(interf
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/ClearMsg",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).ClearMsg(ctx, req.(*ClearMsgReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_SetMsgMinSeq_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_SetMsgMinSeq_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(SetMsgMinSeqReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2823,13 +2823,13 @@ func _Msg_SetMsgMinSeq_Handler(srv interface{}, ctx context.Context, dec func(in
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/SetMsgMinSeq",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).SetMsgMinSeq(ctx, req.(*SetMsgMinSeqReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_SetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_SetSendMsgStatus_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(SetSendMsgStatusReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2841,13 +2841,13 @@ func _Msg_SetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec fun
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/SetSendMsgStatus",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).SetSendMsgStatus(ctx, req.(*SetSendMsgStatusReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_GetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_GetSendMsgStatus_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetSendMsgStatusReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2859,13 +2859,13 @@ func _Msg_GetSendMsgStatus_Handler(srv interface{}, ctx context.Context, dec fun
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/GetSendMsgStatus",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).GetSendMsgStatus(ctx, req.(*GetSendMsgStatusReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_GetSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_GetSuperGroupMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetSuperGroupMsgReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2877,13 +2877,13 @@ func _Msg_GetSuperGroupMsg_Handler(srv interface{}, ctx context.Context, dec fun
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/GetSuperGroupMsg",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).GetSuperGroupMsg(ctx, req.(*GetSuperGroupMsgReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_GetWriteDiffMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_GetWriteDiffMsg_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetWriteDiffMsgReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2895,13 +2895,13 @@ func _Msg_GetWriteDiffMsg_Handler(srv interface{}, ctx context.Context, dec func
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/GetWriteDiffMsg",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).GetWriteDiffMsg(ctx, req.(*GetWriteDiffMsgReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_SetMessageReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_SetMessageReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(SetMessageReactionExtensionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2913,13 +2913,13 @@ func _Msg_SetMessageReactionExtensions_Handler(srv interface{}, ctx context.Cont
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/SetMessageReactionExtensions",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).SetMessageReactionExtensions(ctx, req.(*SetMessageReactionExtensionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_GetMessageListReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_GetMessageListReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(GetMessageListReactionExtensionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2931,13 +2931,13 @@ func _Msg_GetMessageListReactionExtensions_Handler(srv interface{}, ctx context.
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/GetMessageListReactionExtensions",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).GetMessageListReactionExtensions(ctx, req.(*GetMessageListReactionExtensionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_AddMessageReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_AddMessageReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(AddMessageReactionExtensionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2949,13 +2949,13 @@ func _Msg_AddMessageReactionExtensions_Handler(srv interface{}, ctx context.Cont
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/AddMessageReactionExtensions",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).AddMessageReactionExtensions(ctx, req.(*AddMessageReactionExtensionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Msg_DeleteMessageReactionExtensions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Msg_DeleteMessageReactionExtensions_Handler(srv any, ctx context.Context, dec func(any) error, interceptor grpc.UnaryServerInterceptor) (any, error) {
|
||||
in := new(DeleteMessageListReactionExtensionsReq)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
@@ -2967,7 +2967,7 @@ func _Msg_DeleteMessageReactionExtensions_Handler(srv interface{}, ctx context.C
|
||||
Server: srv,
|
||||
FullMethod: "/msg.msg/DeleteMessageReactionExtensions",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
handler := func(ctx context.Context, req any) (any, error) {
|
||||
return srv.(MsgServer).DeleteMessageReactionExtensions(ctx, req.(*DeleteMessageListReactionExtensionsReq))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
|
||||
@@ -4156,8 +4156,8 @@ func (m *SignalReq) GetGetTokenByRoomID() *SignalGetTokenByRoomIDReq {
|
||||
}
|
||||
|
||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
||||
func (*SignalReq) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
||||
return _SignalReq_OneofMarshaler, _SignalReq_OneofUnmarshaler, _SignalReq_OneofSizer, []interface{}{
|
||||
func (*SignalReq) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []any) {
|
||||
return _SignalReq_OneofMarshaler, _SignalReq_OneofUnmarshaler, _SignalReq_OneofSizer, []any{
|
||||
(*SignalReq_Invite)(nil),
|
||||
(*SignalReq_InviteInGroup)(nil),
|
||||
(*SignalReq_Cancel)(nil),
|
||||
@@ -4523,8 +4523,8 @@ func (m *SignalResp) GetGetTokenByRoomID() *SignalGetTokenByRoomIDReply {
|
||||
}
|
||||
|
||||
// XXX_OneofFuncs is for the internal use of the proto package.
|
||||
func (*SignalResp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
|
||||
return _SignalResp_OneofMarshaler, _SignalResp_OneofUnmarshaler, _SignalResp_OneofSizer, []interface{}{
|
||||
func (*SignalResp) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []any) {
|
||||
return _SignalResp_OneofMarshaler, _SignalResp_OneofUnmarshaler, _SignalResp_OneofSizer, []any{
|
||||
(*SignalResp_Invite)(nil),
|
||||
(*SignalResp_InviteInGroup)(nil),
|
||||
(*SignalResp_Cancel)(nil),
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# README for OpenIM Server Data Conversion Tool
|
||||
|
||||
## Overview
|
||||
|
||||
This tool is part of the OpenIM Server suite, specifically designed for data conversion between MySQL and MongoDB databases. It handles the migration of various data types, including user information, friendships, group memberships, and more from a MySQL database to MongoDB, ensuring data consistency and integrity during the transition.
|
||||
|
||||
## Features
|
||||
|
||||
+ **Configurable Database Connections:** Supports connections to both MySQL and MongoDB, configurable through a YAML file.
|
||||
+ **Data Conversion Tasks:** Converts a range of data models, including user profiles, friend requests, group memberships, and logs.
|
||||
+ **Version Control:** Maintains data versioning, ensuring only necessary migrations are performed.
|
||||
+ **Error Handling:** Robust error handling for database connectivity and query execution.
|
||||
|
||||
## Requirements
|
||||
|
||||
+ Go programming environment
|
||||
+ MySQL and MongoDB servers
|
||||
+ OpenIM Server dependencies installed
|
||||
|
||||
## Installation
|
||||
|
||||
1. Ensure Go is installed and set up on your system.
|
||||
2. Clone the OpenIM Server repository.
|
||||
3. Navigate to the directory containing this tool.
|
||||
4. Install required dependencies.
|
||||
|
||||
## Configuration
|
||||
|
||||
+ Configuration is managed through a YAML file specified at runtime.
|
||||
+ Set up the MySQL and MongoDB connection parameters in the config file.
|
||||
|
||||
## Usage
|
||||
|
||||
To run the tool, use the following command from the terminal:
|
||||
|
||||
```go
|
||||
make build BINS="up35"
|
||||
```
|
||||
|
||||
Where `path/to/config.yaml` is the path to your configuration file.
|
||||
|
||||
## Functionality
|
||||
|
||||
The main functions of the script include:
|
||||
|
||||
+ `InitConfig(path string)`: Reads and parses the YAML configuration file.
|
||||
+ `GetMysql()`: Establishes a connection to the MySQL database.
|
||||
+ `GetMongo()`: Establishes a connection to the MongoDB database.
|
||||
+ `Main(path string)`: Orchestrates the data migration process.
|
||||
+ `SetMongoDataVersion(db *mongo.Database, curver string)`: Updates the data version in MongoDB after migration.
|
||||
+ `NewTask(...)`: Generic function to handle the migration of different data types.
|
||||
+ `insertMany(coll *mongo.Collection, objs []any)`: Inserts multiple records into a MongoDB collection.
|
||||
+ `getColl(obj any)`: Retrieves the MongoDB collection associated with a given object.
|
||||
+ `convert struct`: Contains methods for converting MySQL models to MongoDB models.
|
||||
|
||||
## Notes
|
||||
|
||||
+ Ensure that the MySQL and MongoDB instances are accessible and that the credentials provided in the config file are correct.
|
||||
+ It is advisable to backup databases before running the migration to prevent data loss.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to improve the tool or address issues are welcome. Please follow the project's contribution guidelines.
|
||||
|
||||
## License
|
||||
|
||||
Refer to the project's license document for usage and distribution rights.
|
||||
@@ -0,0 +1,51 @@
|
||||
module github.com/openimsdk/open-im-server/v3/tools/up35
|
||||
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/openimsdk/open-im-server/v3 v3.5.0
|
||||
github.com/openimsdk/open-im-server/v3/tools/data-conversion v0.0.0-00010101000000-000000000000
|
||||
go.mongodb.org/mongo-driver v1.12.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.1
|
||||
gorm.io/gorm v1.25.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/OpenIMSDK/protocol v0.0.31 // indirect
|
||||
github.com/OpenIMSDK/tools v0.0.18 // indirect
|
||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/jinzhu/copier v0.4.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.14.0 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sync v0.4.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/openimsdk/open-im-server/v3 => ./../../../open-im-server
|
||||
github.com/openimsdk/open-im-server/v3/tools/data-conversion => ./../data-conversion
|
||||
)
|
||||
@@ -0,0 +1,125 @@
|
||||
github.com/OpenIMSDK/protocol v0.0.31 h1:ax43x9aqA6EKNXNukS5MT5BSTqkUmwO4uTvbJLtzCgE=
|
||||
github.com/OpenIMSDK/protocol v0.0.31/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y=
|
||||
github.com/OpenIMSDK/tools v0.0.18 h1:h3CvKB90DNd2aIJcOQ99cqgeW6C0na0PzR1TNsfxwL0=
|
||||
github.com/OpenIMSDK/tools v0.0.18/go.mod h1:eg+q4A34Qmu73xkY0mt37FHGMCMfC6CtmOnm0kFEGFI=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
|
||||
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible h1:Y6sqxHMyB1D2YSzWkLibYKgg+SwmyFU9dF2hn6MdTj4=
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
|
||||
github.com/lestrrat-go/strftime v1.0.6 h1:CFGsDEt1pOpFNU+TJB0nhz9jl+K0hZSLE205AhTIGQQ=
|
||||
github.com/lestrrat-go/strftime v1.0.6/go.mod h1:f7jQKgV5nnJpYgdEasS+/y7EsTb8ykN2z68n3TtcTaw=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE=
|
||||
go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
|
||||
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
||||
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw=
|
||||
gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
@@ -0,0 +1,367 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/go-sql-driver/mysql"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/mgo"
|
||||
mongoModel "github.com/openimsdk/open-im-server/v3/pkg/common/db/table/relation"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/db/unrelation"
|
||||
mysqlModel "github.com/openimsdk/open-im-server/v3/tools/data-conversion/openim/mysql/v3"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"gopkg.in/yaml.v3"
|
||||
gormMysql "gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
versionTable = "dataver"
|
||||
versionKey = "data_version"
|
||||
versionValue = 35
|
||||
)
|
||||
|
||||
func main() {
|
||||
var path string
|
||||
flag.StringVar(&path, "c", "", "path config file")
|
||||
flag.Parse()
|
||||
if err := Main(path); err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func InitConfig(path string) error {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return yaml.Unmarshal(data, &config.Config)
|
||||
}
|
||||
|
||||
func GetMysql() (*gorm.DB, error) {
|
||||
conf := config.Config.Mysql
|
||||
mysqlDSN := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", conf.Username, conf.Password, conf.Address[0], conf.Database)
|
||||
return gorm.Open(gormMysql.Open(mysqlDSN), &gorm.Config{Logger: logger.Discard})
|
||||
}
|
||||
|
||||
func GetMongo() (*mongo.Database, error) {
|
||||
mgo, err := unrelation.NewMongo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mgo.GetDatabase(), nil
|
||||
}
|
||||
|
||||
func Main(path string) error {
|
||||
if err := InitConfig(path); err != nil {
|
||||
return err
|
||||
}
|
||||
if config.Config.Mysql == nil {
|
||||
return nil
|
||||
}
|
||||
mongoDB, err := GetMongo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var version struct {
|
||||
Key string `bson:"key"`
|
||||
Value string `bson:"value"`
|
||||
}
|
||||
switch mongoDB.Collection(versionTable).FindOne(context.Background(), bson.M{"key": versionKey}).Decode(&version) {
|
||||
case nil:
|
||||
if ver, _ := strconv.Atoi(version.Value); ver >= versionValue {
|
||||
return nil
|
||||
}
|
||||
case mongo.ErrNoDocuments:
|
||||
default:
|
||||
return err
|
||||
}
|
||||
mysqlDB, err := GetMysql()
|
||||
if err != nil {
|
||||
if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1049 {
|
||||
if err := SetMongoDataVersion(mongoDB, version.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil // database not exist
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var c convert
|
||||
var tasks []func() error
|
||||
tasks = append(tasks,
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewUserMongo, c.User) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewFriendMongo, c.Friend) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewFriendRequestMongo, c.FriendRequest) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewBlackMongo, c.Black) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupMongo, c.Group) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupMember, c.GroupMember) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewGroupRequestMgo, c.GroupRequest) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewConversationMongo, c.Conversation) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewS3Mongo, c.Object(config.Config.Object.Enable)) },
|
||||
func() error { return NewTask(mysqlDB, mongoDB, mgo.NewLogMongo, c.Log) },
|
||||
)
|
||||
|
||||
for _, task := range tasks {
|
||||
if err := task(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := SetMongoDataVersion(mongoDB, version.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetMongoDataVersion(db *mongo.Database, curver string) error {
|
||||
filter := bson.M{"key": versionKey, "value": curver}
|
||||
update := bson.M{"$set": bson.M{"key": versionKey, "value": strconv.Itoa(versionValue)}}
|
||||
_, err := db.Collection(versionTable).UpdateOne(context.Background(), filter, update, options.Update().SetUpsert(true))
|
||||
return err
|
||||
}
|
||||
|
||||
// NewTask A mysql table B mongodb model C mongodb table
|
||||
func NewTask[A interface{ TableName() string }, B any, C any](gormDB *gorm.DB, mongoDB *mongo.Database, mongoDBInit func(db *mongo.Database) (B, error), convert func(v A) C) error {
|
||||
obj, err := mongoDBInit(mongoDB)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var zero A
|
||||
tableName := zero.TableName()
|
||||
coll, err := getColl(obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get mongo collection %s failed, err: %w", tableName, err)
|
||||
}
|
||||
var count int
|
||||
defer func() {
|
||||
log.Printf("completed convert %s total %d\n", tableName, count)
|
||||
}()
|
||||
const batch = 100
|
||||
for page := 0; ; page++ {
|
||||
res := make([]A, 0, batch)
|
||||
if err := gormDB.Limit(batch).Offset(page * batch).Find(&res).Error; err != nil {
|
||||
if mysqlErr, ok := err.(*mysql.MySQLError); ok && mysqlErr.Number == 1146 {
|
||||
return nil // table not exist
|
||||
}
|
||||
return fmt.Errorf("find mysql table %s failed, err: %w", tableName, err)
|
||||
}
|
||||
if len(res) == 0 {
|
||||
return nil
|
||||
}
|
||||
temp := make([]any, len(res))
|
||||
for i := range res {
|
||||
temp[i] = convert(res[i])
|
||||
}
|
||||
if err := insertMany(coll, temp); err != nil {
|
||||
return fmt.Errorf("insert mongo table %s failed, err: %w", tableName, err)
|
||||
}
|
||||
count += len(res)
|
||||
if len(res) < batch {
|
||||
return nil
|
||||
}
|
||||
log.Printf("current convert %s completed %d\n", tableName, count)
|
||||
}
|
||||
}
|
||||
|
||||
func insertMany(coll *mongo.Collection, objs []any) error {
|
||||
if _, err := coll.InsertMany(context.Background(), objs); err != nil {
|
||||
if !mongo.IsDuplicateKeyError(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for i := range objs {
|
||||
_, err := coll.InsertOne(context.Background(), objs[i])
|
||||
switch {
|
||||
case err == nil:
|
||||
case mongo.IsDuplicateKeyError(err):
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getColl(obj any) (_ *mongo.Collection, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("not found %+v", e)
|
||||
}
|
||||
}()
|
||||
stu := reflect.ValueOf(obj).Elem()
|
||||
typ := reflect.TypeOf(&mongo.Collection{}).String()
|
||||
for i := 0; i < stu.NumField(); i++ {
|
||||
field := stu.Field(i)
|
||||
if field.Type().String() == typ {
|
||||
return (*mongo.Collection)(field.UnsafePointer()), nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("not found")
|
||||
}
|
||||
|
||||
type convert struct{}
|
||||
|
||||
func (convert) User(v mysqlModel.UserModel) mongoModel.UserModel {
|
||||
return mongoModel.UserModel{
|
||||
UserID: v.UserID,
|
||||
Nickname: v.Nickname,
|
||||
FaceURL: v.FaceURL,
|
||||
Ex: v.Ex,
|
||||
AppMangerLevel: v.AppMangerLevel,
|
||||
GlobalRecvMsgOpt: v.GlobalRecvMsgOpt,
|
||||
CreateTime: v.CreateTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) Friend(v mysqlModel.FriendModel) mongoModel.FriendModel {
|
||||
return mongoModel.FriendModel{
|
||||
OwnerUserID: v.OwnerUserID,
|
||||
FriendUserID: v.FriendUserID,
|
||||
Remark: v.Remark,
|
||||
CreateTime: v.CreateTime,
|
||||
AddSource: v.AddSource,
|
||||
OperatorUserID: v.OperatorUserID,
|
||||
Ex: v.Ex,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) FriendRequest(v mysqlModel.FriendRequestModel) mongoModel.FriendRequestModel {
|
||||
return mongoModel.FriendRequestModel{
|
||||
FromUserID: v.FromUserID,
|
||||
ToUserID: v.ToUserID,
|
||||
HandleResult: v.HandleResult,
|
||||
ReqMsg: v.ReqMsg,
|
||||
CreateTime: v.CreateTime,
|
||||
HandlerUserID: v.HandlerUserID,
|
||||
HandleMsg: v.HandleMsg,
|
||||
HandleTime: v.HandleTime,
|
||||
Ex: v.Ex,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) Black(v mysqlModel.BlackModel) mongoModel.BlackModel {
|
||||
return mongoModel.BlackModel{
|
||||
OwnerUserID: v.OwnerUserID,
|
||||
BlockUserID: v.BlockUserID,
|
||||
CreateTime: v.CreateTime,
|
||||
AddSource: v.AddSource,
|
||||
OperatorUserID: v.OperatorUserID,
|
||||
Ex: v.Ex,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) Group(v mysqlModel.GroupModel) mongoModel.GroupModel {
|
||||
return mongoModel.GroupModel{
|
||||
GroupID: v.GroupID,
|
||||
GroupName: v.GroupName,
|
||||
Notification: v.Notification,
|
||||
Introduction: v.Introduction,
|
||||
FaceURL: v.FaceURL,
|
||||
CreateTime: v.CreateTime,
|
||||
Ex: v.Ex,
|
||||
Status: v.Status,
|
||||
CreatorUserID: v.CreatorUserID,
|
||||
GroupType: v.GroupType,
|
||||
NeedVerification: v.NeedVerification,
|
||||
LookMemberInfo: v.LookMemberInfo,
|
||||
ApplyMemberFriend: v.ApplyMemberFriend,
|
||||
NotificationUpdateTime: v.NotificationUpdateTime,
|
||||
NotificationUserID: v.NotificationUserID,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) GroupMember(v mysqlModel.GroupMemberModel) mongoModel.GroupMemberModel {
|
||||
return mongoModel.GroupMemberModel{
|
||||
GroupID: v.GroupID,
|
||||
UserID: v.UserID,
|
||||
Nickname: v.Nickname,
|
||||
FaceURL: v.FaceURL,
|
||||
RoleLevel: v.RoleLevel,
|
||||
JoinTime: v.JoinTime,
|
||||
JoinSource: v.JoinSource,
|
||||
InviterUserID: v.InviterUserID,
|
||||
OperatorUserID: v.OperatorUserID,
|
||||
MuteEndTime: v.MuteEndTime,
|
||||
Ex: v.Ex,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) GroupRequest(v mysqlModel.GroupRequestModel) mongoModel.GroupRequestModel {
|
||||
return mongoModel.GroupRequestModel{
|
||||
UserID: v.UserID,
|
||||
GroupID: v.GroupID,
|
||||
HandleResult: v.HandleResult,
|
||||
ReqMsg: v.ReqMsg,
|
||||
HandledMsg: v.HandledMsg,
|
||||
ReqTime: v.ReqTime,
|
||||
HandleUserID: v.HandleUserID,
|
||||
HandledTime: v.HandledTime,
|
||||
JoinSource: v.JoinSource,
|
||||
InviterUserID: v.InviterUserID,
|
||||
Ex: v.Ex,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) Conversation(v mysqlModel.ConversationModel) mongoModel.ConversationModel {
|
||||
return mongoModel.ConversationModel{
|
||||
OwnerUserID: v.OwnerUserID,
|
||||
ConversationID: v.ConversationID,
|
||||
ConversationType: v.ConversationType,
|
||||
UserID: v.UserID,
|
||||
GroupID: v.GroupID,
|
||||
RecvMsgOpt: v.RecvMsgOpt,
|
||||
IsPinned: v.IsPinned,
|
||||
IsPrivateChat: v.IsPrivateChat,
|
||||
BurnDuration: v.BurnDuration,
|
||||
GroupAtType: v.GroupAtType,
|
||||
AttachedInfo: v.AttachedInfo,
|
||||
Ex: v.Ex,
|
||||
MaxSeq: v.MaxSeq,
|
||||
MinSeq: v.MinSeq,
|
||||
CreateTime: v.CreateTime,
|
||||
IsMsgDestruct: v.IsMsgDestruct,
|
||||
MsgDestructTime: v.MsgDestructTime,
|
||||
LatestMsgDestructTime: v.LatestMsgDestructTime,
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) Object(engine string) func(v mysqlModel.ObjectModel) mongoModel.ObjectModel {
|
||||
return func(v mysqlModel.ObjectModel) mongoModel.ObjectModel {
|
||||
return mongoModel.ObjectModel{
|
||||
Name: v.Name,
|
||||
UserID: v.UserID,
|
||||
Hash: v.Hash,
|
||||
Engine: engine,
|
||||
Key: v.Key,
|
||||
Size: v.Size,
|
||||
ContentType: v.ContentType,
|
||||
Group: v.Cause,
|
||||
CreateTime: v.CreateTime,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (convert) Log(v mysqlModel.Log) mongoModel.LogModel {
|
||||
return mongoModel.LogModel{
|
||||
LogID: v.LogID,
|
||||
Platform: v.Platform,
|
||||
UserID: v.UserID,
|
||||
CreateTime: v.CreateTime,
|
||||
Url: v.Url,
|
||||
FileName: v.FileName,
|
||||
SystemType: v.SystemType,
|
||||
Version: v.Version,
|
||||
Ex: v.Ex,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user