feat: incr sync version.

This commit is contained in:
Gordon
2024-06-24 17:48:33 +08:00
parent e8ccae6349
commit 88b8043224
308 changed files with 55952 additions and 59 deletions

View File

@@ -0,0 +1,59 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) InsertAdminGroupRequest(ctx context.Context, groupRequest *model_struct.LocalAdminGroupRequest) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupRequest).Error, "InsertAdminGroupRequest failed")
}
func (d *DataBase) DeleteAdminGroupRequest(ctx context.Context, groupID, userID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&model_struct.LocalAdminGroupRequest{}).Error, "DeleteAdminGroupRequest failed")
}
func (d *DataBase) UpdateAdminGroupRequest(ctx context.Context, groupRequest *model_struct.LocalAdminGroupRequest) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
t := d.conn.WithContext(ctx).Model(groupRequest).Select("*").Updates(*groupRequest)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.Wrap(t.Error)
}
func (d *DataBase) GetAdminGroupApplication(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupRequestList []*model_struct.LocalAdminGroupRequest
err := errs.Wrap(d.conn.WithContext(ctx).Order("create_time DESC").Find(&groupRequestList).Error)
if err != nil {
return nil, errs.Wrap(err)
}
return groupRequestList, nil
}

View File

@@ -0,0 +1,34 @@
package db
import (
"context"
"github.com/openimsdk/tools/errs"
"gorm.io/gorm"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
)
func (d *DataBase) GetAppSDKVersion(ctx context.Context) (*model_struct.LocalAppSDKVersion, error) {
var appVersion model_struct.LocalAppSDKVersion
return &appVersion, errs.Wrap(d.conn.WithContext(ctx).Take(&appVersion).Error)
}
func (d *DataBase) SetAppSDKVersion(ctx context.Context, appVersion *model_struct.LocalAppSDKVersion) error {
var exist model_struct.LocalAppSDKVersion
err := d.conn.WithContext(ctx).First(&exist).Error
if err == gorm.ErrRecordNotFound {
if createErr := d.conn.WithContext(ctx).Create(appVersion).Error; createErr != nil {
return errs.Wrap(createErr)
}
return nil
} else if err != nil {
return errs.Wrap(err)
}
if updateErr := d.conn.WithContext(ctx).Model(&exist).Updates(appVersion).Error; updateErr != nil {
return errs.Wrap(updateErr)
}
return nil
}

View File

@@ -0,0 +1,79 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) GetBlackListDB(ctx context.Context) ([]*model_struct.LocalBlack, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var blackList []*model_struct.LocalBlack
return blackList, errs.Wrap(d.conn.WithContext(ctx).Find(&blackList).Error)
}
func (d *DataBase) GetBlackListUserID(ctx context.Context) (blackListUid []string, err error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return blackListUid, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalBlack{}).Select("block_user_id").Find(&blackListUid).Error, "GetBlackList failed")
}
func (d *DataBase) GetBlackInfoByBlockUserID(ctx context.Context, blockUserID string) (*model_struct.LocalBlack, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var black model_struct.LocalBlack
return &black, errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ? AND block_user_id = ? ",
d.loginUserID, blockUserID).Take(&black).Error, "GetBlackInfoByBlockUserID failed")
}
func (d *DataBase) GetBlackInfoList(ctx context.Context, blockUserIDList []string) ([]*model_struct.LocalBlack, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var blackList []*model_struct.LocalBlack
if err := d.conn.WithContext(ctx).Where("block_user_id IN ? ", blockUserIDList).Find(&blackList).Error; err != nil {
return nil, errs.WrapMsg(err, "GetBlackInfoList failed")
}
return blackList, nil
}
func (d *DataBase) InsertBlack(ctx context.Context, black *model_struct.LocalBlack) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(black).Error, "InsertBlack failed")
}
func (d *DataBase) UpdateBlack(ctx context.Context, black *model_struct.LocalBlack) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
t := d.conn.WithContext(ctx).Updates(black)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.WrapMsg(t.Error, "UpdateBlack failed")
}
func (d *DataBase) DeleteBlack(ctx context.Context, blockUserID string) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id=? and block_user_id=?", d.loginUserID, blockUserID).Delete(&model_struct.LocalBlack{}).Error, "DeleteBlack failed")
}

View File

@@ -0,0 +1,565 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
"gorm.io/gorm"
)
// funcation (d *DataBase) BatchInsertMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error {
// if MessageList == nil {
// return nil
// }
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// return utils.Wrap(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertMessageList failed")
// }
//funcation (d *DataBase) BatchInsertMessageListController(ctx context.Context, MessageList []*model_struct.LocalChatLog) error {
// if len(MessageList) == 0 {
// return nil
// }
// switch MessageList[len(MessageList)-1].SessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupBatchInsertMessageList(ctx, MessageList, MessageList[len(MessageList)-1].RecvID)
// default:
// return d.BatchInsertMessageList(ctx, MessageList)
// }
//}
// funcation (d *DataBase) InsertMessage(ctx context.Context, Message *model_struct.LocalChatLog) error {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// return utils.Wrap(d.conn.WithContext(ctx).Create(Message).Error, "InsertMessage failed")
// }
//
// funcation (d *DataBase) InsertMessageController(ctx context.Context, message *model_struct.LocalChatLog) error {
// switch message.SessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupInsertMessage(ctx, message, message.RecvID)
// default:
// return d.InsertMessage(ctx, message)
// }
// }
//funcation (d *DataBase) SearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) {
// var messageList []model_struct.LocalChatLog
// var condition string
// var subCondition string
// if keywordListMatchType == constant.KeywordMatchOr {
// for i := 0; i < len(keywordList); i++ {
// if i == 0 {
// subCondition += "And ("
// }
// if i+1 >= len(keywordList) {
// subCondition += "content like " + "'%" + keywordList[i] + "%') "
// } else {
// subCondition += "content like " + "'%" + keywordList[i] + "%' " + "or "
//
// }
// }
// } else {
// for i := 0; i < len(keywordList); i++ {
// if i == 0 {
// subCondition += "And ("
// }
// if i+1 >= len(keywordList) {
// subCondition += "content like " + "'%" + keywordList[i] + "%') "
// } else {
// subCondition += "content like " + "'%" + keywordList[i] + "%' " + "and "
// }
// }
// }
// switch sessionType {
// case constant.SingleChatType, constant.NotificationChatType:
// condition = fmt.Sprintf("session_type==%d And (send_id==%q OR recv_id==%q) And send_time between %d and %d AND status <=%d And content_type IN ? ", constant.SingleChatType, sourceID, sourceID, startTime, endTime, constant.MsgStatusSendFailed)
// case constant.GroupChatType:
// condition = fmt.Sprintf("session_type==%d And recv_id==%q And send_time between %d and %d AND status <=%d And content_type IN ? ", constant.GroupChatType, sourceID, startTime, endTime, constant.MsgStatusSendFailed)
// default:
// //condition = fmt.Sprintf("(send_id==%q OR recv_id==%q) And send_time between %d and %d AND status <=%d And content_type == %d And content like %q", sourceID, sourceID, startTime, endTime, constant.MsgStatusSendFailed, constant.Text, "%"+keyword+"%")
// return nil, err
// }
// condition += subCondition
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "InsertMessage failed")
//
// for _, v := range messageList {
// v1 := v
// result = append(result, &v1)
// }
// return result, err
//}
//funcation (d *DataBase) SearchMessageByKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) {
// switch sessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupSearchMessageByKeyword(ctx, contentType, keywordList, keywordListMatchType, sourceID, startTime, endTime, sessionType, offset, count)
// default:
// return d.SearchMessageByKeyword(ctx, contentType, keywordList, keywordListMatchType, sourceID, startTime, endTime, sessionType, offset, count)
// }
//}
//funcation (d *DataBase) SearchMessageByContentType(ctx context.Context, contentType []int,conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) {
// var messageList []model_struct.LocalChatLog
// var condition string
// switch sessionType {
// case constant.SingleChatType, constant.NotificationChatType:
// condition = fmt.Sprintf("session_type==%d And (send_id==%q OR recv_id==%q) And send_time between %d and %d AND status <=%d And content_type IN ?", constant.SingleChatType, sourceID, sourceID, startTime, endTime, constant.MsgStatusSendFailed)
// case constant.GroupChatType:
// condition = fmt.Sprintf("session_type==%d And recv_id==%q And send_time between %d and %d AND status <=%d And content_type IN ?", constant.GroupChatType, sourceID, startTime, endTime, constant.MsgStatusSendFailed)
// default:
// return nil, err
// }
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "SearchMessage failed")
// for _, v := range messageList {
// v1 := v
// result = append(result, &v1)
// }
// return result, err
//}
//funcation (d *DataBase) SearchMessageByContentTypeController(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) {
// switch sessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupSearchMessageByContentType(ctx, contentType, sourceID, startTime, endTime, sessionType, offset, count)
// default:
// return d.SearchMessageByContentType(ctx, contentType, conversationID, startTime, endTime, offset, count)
// }
//}
//funcation (d *DataBase) SearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, conversationID string,keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) {
// var messageList []model_struct.LocalChatLog
// var condition string
// var subCondition string
// if keywordListMatchType == constant.KeywordMatchOr {
// for i := 0; i < len(keywordList); i++ {
// if i == 0 {
// subCondition += "And ("
// }
// if i+1 >= len(keywordList) {
// subCondition += "content like " + "'%" + keywordList[i] + "%') "
// } else {
// subCondition += "content like " + "'%" + keywordList[i] + "%' " + "or "
//
// }
// }
// } else {
// for i := 0; i < len(keywordList); i++ {
// if i == 0 {
// subCondition += "And ("
// }
// if i+1 >= len(keywordList) {
// subCondition += "content like " + "'%" + keywordList[i] + "%') "
// } else {
// subCondition += "content like " + "'%" + keywordList[i] + "%' " + "and "
// }
// }
// }
// condition = fmt.Sprintf("send_time between %d and %d AND status <=%d And content_type IN ? ", startTime, endTime, constant.MsgStatusSendFailed)
// condition += subCondition
// log.Info("key owrd", condition)
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, contentType).Order("send_time DESC").Find(&messageList).Error, "SearchMessage failed")
// for _, v := range messageList {
// v1 := v
// result = append(result, &v1)
// }
// return result, err
//}
//funcation (d *DataBase) BatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error {
// if MessageList == nil {
// return nil
// }
//
// for _, v := range MessageList {
// v1 := new(model_struct.LocalChatLog)
// v1.ClientMsgID = v.ClientMsgID
// v1.Seq = v.Seq
// v1.Status = v.Status
// v1.RecvID = v.RecvID
// v1.SessionType = v.SessionType
// v1.ServerMsgID = v.ServerMsgID
// err := d.UpdateMessageController(ctx, v1)
// if err != nil {
// return utils.Wrap(err, "BatchUpdateMessageList failed")
// }
//
// }
// return nil
//}
//funcation (d *DataBase) BatchSpecialUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error {
// if MessageList == nil {
// return nil
// }
//
// for _, v := range MessageList {
// v1 := new(model_struct.LocalChatLog)
// v1.ClientMsgID = v.ClientMsgID
// v1.ServerMsgID = v.ServerMsgID
// v1.SendID = v.SendID
// v1.RecvID = v.RecvID
// v1.SenderPlatformID = v.SenderPlatformID
// v1.SenderNickname = v.SenderNickname
// v1.SenderFaceURL = v.SenderFaceURL
// v1.SessionType = v.SessionType
// v1.MsgFrom = v.MsgFrom
// v1.ContentType = v.ContentType
// v1.Content = v.Content
// v1.Seq = v.Seq
// v1.SendTime = v.SendTime
// v1.CreateTime = v.CreateTime
// v1.AttachedInfo = v.AttachedInfo
// v1.Ex = v.Ex
// err := d.UpdateMessageController(ctx, v1)
// if err != nil {
// log.Error("", "update single message failed", *v)
// return utils.Wrap(err, "BatchUpdateMessageList failed")
// }
//
// }
// return nil
//}
func (d *DataBase) MessageIfExists(ctx context.Context, ClientMsgID string) (bool, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var count int64
t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("client_msg_id = ?",
ClientMsgID).Count(&count)
if t.Error != nil {
return false, utils.Wrap(t.Error, "MessageIfExists get failed")
}
if count != 1 {
return false, nil
} else {
return true, nil
}
}
func (d *DataBase) IsExistsInErrChatLogBySeq(ctx context.Context, seq int64) bool {
return true
}
func (d *DataBase) MessageIfExistsBySeq(ctx context.Context, seq int64) (bool, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var count int64
t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("seq = ?",
seq).Count(&count)
if t.Error != nil {
return false, utils.Wrap(t.Error, "MessageIfExistsBySeq get failed")
}
if count != 1 {
return false, nil
} else {
return true, nil
}
}
// funcation (d *DataBase) GetMessage(ctx context.Context, ClientMsgID string) (*model_struct.LocalChatLog, error) {
// var c model_struct.LocalChatLog
// return &c, utils.Wrap(d.conn.WithContext(ctx).Where("client_msg_id = ?",
// ClientMsgID).Take(&c).Error, "GetMessage failed")
// }
//funcation (d *DataBase) GetMessageController(ctx context.Context, msg *sdk_struct.MsgStruct) (*model_struct.LocalChatLog, error) {
// switch msg.SessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupGetMessage(ctx, msg)
// default:
// return d.GetMessage(ctx, msg.ClientMsgID)
// }
//}
func (d *DataBase) GetAllUnDeleteMessageSeqList(ctx context.Context) ([]uint32, error) {
var seqList []uint32
return seqList, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("status != ?", constant.MsgStatusHasDeleted).Select("seq").Find(&seqList).Error, "")
}
func (d *DataBase) UpdateColumnsMessageList(ctx context.Context, clientMsgIDList []string, args map[string]interface{}) error {
c := model_struct.LocalChatLog{}
t := d.conn.WithContext(ctx).Model(&c).Where("client_msg_id IN", clientMsgIDList).Updates(args)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateColumnsConversation failed")
}
//funcation (d *DataBase) UpdateColumnsMessageController(ctx context.Context, ClientMsgID string, groupID string, sessionType int32, args map[string]interface{}) error {
// switch sessionType {
// case constant.SuperGroupChatType:
// return utils.Wrap(d.SuperGroupUpdateColumnsMessage(ctx, ClientMsgID, groupID, args), "")
// default:
// return utils.Wrap(d.UpdateColumnsMessage(ctx, ClientMsgID, args), "")
// }
//}
// funcation (d *DataBase) UpdateMessage(ctx context.Context, c *model_struct.LocalChatLog) error {
// t := d.conn.WithContext(ctx).Updates(c)
// if t.RowsAffected == 0 {
// return utils.Wrap(errors.New("RowsAffected == 0"), "no update ")
// }
// return utils.Wrap(t.Error, "UpdateMessage failed")
// }
//funcation (d *DataBase) UpdateMessageController(ctx context.Context, c *model_struct.LocalChatLog) error {
// switch c.SessionType {
// case constant.SuperGroupChatType:
// return utils.Wrap(d.SuperGroupUpdateMessage(ctx, c), "")
// default:
// return utils.Wrap(d.UpdateMessage(ctx, c), "")
// }
//}
func (d *DataBase) DeleteAllMessage(ctx context.Context) error {
m := model_struct.LocalChatLog{Status: constant.MsgStatusHasDeleted, Content: ""}
err := d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Select("status", "content").Updates(m).Error
return utils.Wrap(err, "delete all message error")
}
func (d *DataBase) UpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var condition string
if sourceID == d.loginUserID && sessionType == constant.SingleChatType {
condition = "send_id=? And recv_id=? AND session_type=?"
} else {
condition = "(send_id=? or recv_id=?)AND session_type=?"
}
t := d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(condition, sourceID, sourceID, sessionType).Updates(model_struct.LocalChatLog{Status: status})
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) UpdateMessageStatusBySourceIDController(ctx context.Context, sourceID string, status, sessionType int32) error {
switch sessionType {
case constant.SuperGroupChatType:
return d.SuperGroupUpdateMessageStatusBySourceID(ctx, sourceID, status, sessionType)
default:
return d.UpdateMessageStatusBySourceID(ctx, sourceID, status, sessionType)
}
}
// funcation (d *DataBase) UpdateMessageTimeAndStatus(ctx context.Context, clientMsgID string, serverMsgID string, sendTime int64, status int32) error {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where("client_msg_id=? And seq=?", clientMsgID, 0).
// Updates(model_struct.LocalChatLog{Status: status, SendTime: sendTime, ServerMsgID: serverMsgID}).Error, "UpdateMessageStatusBySourceID failed")
//
// }
//funcation (d *DataBase) UpdateMessageTimeAndStatusController(ctx context.Context, msg *sdk_struct.MsgStruct) error {
// switch msg.SessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupUpdateMessageTimeAndStatus(ctx, msg)
// default:
// return d.UpdateMessageTimeAndStatus(ctx, msg.ClientMsgID, msg.ServerMsgID, msg.SendTime, msg.Status)
// }
//}
//funcation (d *DataBase) UpdateMessageAttachedInfo(ctx context.Context, msg *sdk_struct.MsgStruct) error {
// info, err := json.Marshal(msg.AttachedInfoElem)
// if err != nil {
// return err
// }
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// switch msg.SessionType {
// case constant.SuperGroupChatType:
// t := d.conn.WithContext(ctx).Table(utils.GetSuperGroupTableName(msg.GroupID)).Where("client_msg_id=?", msg.ClientMsgID).Updates(map[string]any{"attached_info": string(info)})
// if t.RowsAffected == 0 {
// return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
// }
// return utils.Wrap(t.Error, "SuperGroupUpdateMessageTimeAndStatus failed")
// default:
// return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where("client_msg_id=?", msg.ClientMsgID).Updates(map[string]any{"attached_info": string(info)}).Error, "")
// }
//}
// group ,index_recv_id and index_send_time only one can be used,when index_recv_id be used,temp B tree use for order by,Query speed decrease
//funcation (d *DataBase) GetMessageList(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// var messageList []model_struct.LocalChatLog
// var condition, timeOrder, timeSymbol string
// if isReverse {
// timeOrder = "send_time ASC"
// timeSymbol = ">"
// } else {
// timeOrder = "send_time DESC"
// timeSymbol = "<"
// }
// if sessionType == constant.SingleChatType && sourceID == d.loginUserID {
// condition = "send_id = ? And recv_id = ? AND status <=? And session_type = ? And send_time " + timeSymbol + " ?"
// } else {
// condition = "(send_id = ? OR recv_id = ?) AND status <=? And session_type = ? And send_time " + timeSymbol + " ?"
// }
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, sourceID, sourceID, constant.MsgStatusSendFailed, sessionType, startTime).
// Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed")
// for _, v := range messageList {
// v1 := v
// result = append(result, &v1)
// }
// return result, err
//}
func (d *DataBase) GetAllMessageForTest(ctx context.Context) (result []*model_struct.LocalChatLog, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var messageList []model_struct.LocalChatLog
err = utils.Wrap(d.conn.WithContext(ctx).Find(&messageList).Error, "GetMessageList failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
//funcation (d *DataBase) GetMessageListController(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
// switch sessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupGetMessageList(ctx, sourceID, sessionType, count, startTime, isReverse)
// default:
// return d.GetMessageList(ctx, sourceID, sessionType, count, startTime, isReverse)
// }
//}
//funcation (d *DataBase) GetMessageListNoTime(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// var messageList []model_struct.LocalChatLog
// var condition, timeOrder string
// if isReverse {
// timeOrder = "send_time ASC"
// } else {
// timeOrder = "send_time DESC"
// }
// switch sessionType {
// case constant.SingleChatType:
// if sourceID == d.loginUserID {
// condition = "send_id = ? And recv_id = ? AND status <=? And session_type = ?"
// } else {
// condition = "(send_id = ? OR recv_id = ?) AND status <=? And session_type = ? "
// }
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, sourceID, sourceID, constant.MsgStatusSendFailed, sessionType).
// Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed")
// case constant.GroupChatType:
// condition = " recv_id = ? AND status <=? And session_type = ? "
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType).
// Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed")
// default:
// condition = "(send_id = ? OR recv_id = ?) AND status <=? And session_type = ? "
// err = utils.Wrap(d.conn.WithContext(ctx).Where(condition, sourceID, sourceID, constant.MsgStatusSendFailed, sessionType).
// Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed")
// }
//
// for _, v := range messageList {
// v1 := v
// result = append(result, &v1)
// }
// return result, err
//}
//funcation (d *DataBase) GetMessageListNoTimeController(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
// switch sessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupGetMessageListNoTime(ctx, sourceID, sessionType, count, isReverse)
// default:
// return d.GetMessageListNoTime(ctx, sourceID, sessionType, count, isReverse)
// }
//}
func (d *DataBase) GetTestMessage(ctx context.Context, seq uint32) (*model_struct.LocalChatLog, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var c model_struct.LocalChatLog
return &c, utils.Wrap(d.conn.WithContext(ctx).Where("seq = ?",
seq).Find(&c).Error, "GetTestMessage failed")
}
func (d *DataBase) UpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(
"send_id = ? and session_type = ? and sender_nick_name != ? ", sendID, sType, nickname).Updates(
map[string]interface{}{"sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed")
}
func (d *DataBase) UpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(
"send_id = ? and session_type = ? and sender_face_url != ? ", sendID, sType, faceURL).Updates(
map[string]interface{}{"sender_face_url": faceURL}).Error, utils.GetSelfFuncName()+" failed")
}
//funcation (d *DataBase) UpdateMsgSenderFaceURLAndSenderNicknameController(ctx context.Context, sendID, faceURL, nickname string, sessionType int, groupID string) error {
// switch sessionType {
// case constant.SuperGroupChatType:
// return d.SuperGroupUpdateMsgSenderFaceURLAndSenderNickname(ctx, sendID, faceURL, nickname, sessionType, groupID)
// default:
// return d.UpdateMsgSenderFaceURLAndSenderNickname(ctx, sendID, faceURL, nickname, sessionType)
// }
//}
//funcation (d *DataBase) UpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, sendID, faceURL, nickname string, sessionType int) error {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(
// "send_id = ? and session_type = ?", sendID, sessionType).Updates(
// map[string]interface{}{"sender_face_url": faceURL, "sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed")
//}
func (d *DataBase) GetMsgSeqByClientMsgID(ctx context.Context, clientMsgID string) (uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seq uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("client_msg_id=?", clientMsgID).First(&seq).Error, utils.GetSelfFuncName()+" failed")
return seq, err
}
func (d *DataBase) GetMsgSeqByClientMsgIDController(ctx context.Context, m *sdk_struct.MsgStruct) (uint32, error) {
switch m.SessionType {
case constant.SuperGroupChatType:
return d.SuperGroupGetMsgSeqByClientMsgID(ctx, m.ClientMsgID, m.GroupID)
default:
return d.GetMsgSeqByClientMsgID(ctx, m.ClientMsgID)
}
}
func (d *DataBase) GetMsgSeqListByGroupID(ctx context.Context, groupID string) ([]uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqList []uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=?", groupID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed")
return seqList, err
}
func (d *DataBase) GetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqList []uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? or send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed")
return seqList, err
}
func (d *DataBase) GetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqList []uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? and send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed")
return seqList, err
}

View File

@@ -0,0 +1,341 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
)
func (d *DataBase) initChatLog(ctx context.Context, conversationID string) {
if !d.conn.Migrator().HasTable(utils.GetTableName(conversationID)) {
d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).AutoMigrate(&model_struct.LocalChatLog{})
result := d.conn.Exec(fmt.Sprintf("CREATE INDEX %s ON %s (seq)", "index_seq_"+conversationID,
utils.GetTableName(conversationID)))
if result.Error != nil {
log.ZError(ctx, "create table seq index failed", result.Error, "conversationID", conversationID)
}
result = d.conn.Exec(fmt.Sprintf("CREATE INDEX %s ON %s (send_time)", "index_send_time_"+conversationID,
utils.GetTableName(conversationID)))
if result.Error != nil {
log.ZError(ctx, "create table send_time index failed", result.Error, "conversationID", conversationID)
}
}
}
func (d *DataBase) UpdateMessage(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error {
t := d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Updates(c)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update ")
}
return errs.WrapMsg(t.Error, "UpdateMessage failed")
}
func (d *DataBase) UpdateMessageBySeq(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq=?", c.Seq).Updates(c).Error, "UpdateMessage failed")
}
func (d *DataBase) BatchInsertMessageList(ctx context.Context, conversationID string, MessageList []*model_struct.LocalChatLog) error {
if MessageList == nil {
return nil
}
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Create(MessageList).Error, "BatchInsertMessageList failed")
}
func (d *DataBase) InsertMessage(ctx context.Context, conversationID string, Message *model_struct.LocalChatLog) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Create(Message).Error, "InsertMessage failed")
}
func (d *DataBase) GetMessage(ctx context.Context, conversationID string, clientMsgID string) (*model_struct.LocalChatLog, error) {
d.initChatLog(ctx, conversationID)
var c model_struct.LocalChatLog
return &c, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("client_msg_id = ?",
clientMsgID).Take(&c).Error, "GetMessage failed")
}
func (d *DataBase) GetMessageBySeq(ctx context.Context, conversationID string, seq int64) (*model_struct.LocalChatLog, error) {
d.initChatLog(ctx, conversationID)
var c model_struct.LocalChatLog
return &c, errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq = ?",
seq).Take(&c).Error, "GetMessage failed")
}
func (d *DataBase) UpdateMessageTimeAndStatus(ctx context.Context, conversationID, clientMsgID string, serverMsgID string, sendTime int64, status int32) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(model_struct.LocalChatLog{}).Where("client_msg_id=? And seq=?", clientMsgID, 0).
Updates(model_struct.LocalChatLog{Status: status, SendTime: sendTime, ServerMsgID: serverMsgID}).Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) GetMessageListNoTime(ctx context.Context, conversationID string,
count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
d.initChatLog(ctx, conversationID)
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var timeOrder string
if isReverse {
timeOrder = "send_time ASC"
} else {
timeOrder = "send_time DESC"
}
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Order(timeOrder).Offset(0).Limit(count).Find(&result).Error, "GetMessageList failed")
if err != nil {
return nil, err
}
return result, err
}
func (d *DataBase) GetMessageList(ctx context.Context, conversationID string, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var condition, timeOrder, timeSymbol string
if isReverse {
timeOrder = "send_time ASC"
timeSymbol = ">"
} else {
timeOrder = "send_time DESC"
timeSymbol = "<"
}
condition = "send_time " + timeSymbol + " ?"
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, startTime).
Order(timeOrder).Offset(0).Limit(count).Find(&result).Error, "GetMessageList failed")
if err != nil {
return nil, err
}
return result, err
}
func (d *DataBase) DeleteConversationAllMessages(ctx context.Context, conversationID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("1 = 1").Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationAllMessages failed")
}
func (d *DataBase) MarkDeleteConversationAllMessages(ctx context.Context, conversationID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("1 = 1").Updates(model_struct.LocalChatLog{Status: constant.MsgStatusHasDeleted}).Error, "DeleteConversationAllMessages failed")
}
func (d *DataBase) DeleteConversationMsgs(ctx context.Context, conversationID string, msgIDs []string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("client_msg_id IN ?", msgIDs).Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationMsgs failed")
}
func (d *DataBase) DeleteConversationMsgsBySeqs(ctx context.Context, conversationID string, seqs []int64) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where("seq IN ?", seqs).Delete(model_struct.LocalChatLog{}).Error, "DeleteConversationMsgs failed")
}
func (d *DataBase) SearchMessageByContentType(ctx context.Context, contentType []int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) {
condition := fmt.Sprintf("send_time between %d and %d AND status <=%d And content_type IN ?", startTime, endTime, constant.MsgStatusSendFailed)
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&result).Error, "SearchMessage failed")
return result, err
}
func (d *DataBase) SearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error) {
var condition string
var subCondition string
if keywordListMatchType == constant.KeywordMatchOr {
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "or "
}
}
} else {
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "and "
}
}
}
condition = fmt.Sprintf(" send_time between %d and %d AND status <=%d And content_type IN ? ", startTime, endTime, constant.MsgStatusSendFailed)
condition += subCondition
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&result).Error, "InsertMessage failed")
return result, err
} // SearchMessageByContentTypeAndKeyword searches for messages in the database that match specified content types and keywords within a given time range.
func (d *DataBase) SearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, conversationID string, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error) {
var condition string
var subCondition string
// Construct a sub-condition for SQL query based on keyword list and match type
if keywordListMatchType == constant.KeywordMatchOr {
// Use OR logic if keywordListMatchType is KeywordMatchOr
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "or "
}
}
} else {
// Use AND logic for other keywordListMatchType
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "and "
}
}
}
// Construct the main SQL condition string
condition = fmt.Sprintf("send_time between %d and %d AND status <=%d And content_type IN ? ", startTime, endTime, constant.MsgStatusSendFailed)
condition += subCondition
// Execute the query using the constructed condition and handle errors
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Where(condition, contentType).Order("send_time DESC").Find(&result).Error, "SearchMessage failed")
return result, err
}
func (d *DataBase) UpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, conversationID, sendID, faceURL, nickname string) error {
return errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(model_struct.LocalChatLog{}).Where(
"send_id = ?", sendID).Updates(
map[string]interface{}{"sender_face_url": faceURL, "sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed")
}
func (d *DataBase) GetAlreadyExistSeqList(ctx context.Context, conversationID string, lostSeqList []int64) (seqList []int64, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq IN ?", lostSeqList).Pluck("seq", &seqList).Error, utils.GetSelfFuncName()+" failed")
if err != nil {
return nil, err
}
return seqList, nil
}
func (d *DataBase) UpdateColumnsMessage(ctx context.Context, conversationID, ClientMsgID string, args map[string]interface{}) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalChatLog{ClientMsgID: ClientMsgID}
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Model(&c).Updates(args)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.WrapMsg(t.Error, "UpdateColumnsConversation failed")
}
func (d *DataBase) SearchAllMessageByContentType(ctx context.Context, conversationID string, contentType int) (result []*model_struct.LocalChatLog, err error) {
err = d.conn.WithContext(ctx).Table(utils.GetTableName(conversationID)).Model(&model_struct.LocalChatLog{}).Where("content_type = ?", contentType).Find(&result).Error
return result, err
}
func (d *DataBase) GetUnreadMessage(ctx context.Context, conversationID string) (msgs []*model_struct.LocalChatLog, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Debug().Where("send_id != ? AND is_read = ?", d.loginUserID, constant.NotRead).Find(&msgs).Error, "GetMessageList failed")
return msgs, err
}
func (d *DataBase) MarkConversationMessageAsReadBySeqs(ctx context.Context, conversationID string, seqs []int64) (rowsAffected int64, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq in ? AND send_id != ?", seqs, d.loginUserID).Update("is_read", constant.HasRead)
if t.RowsAffected == 0 {
return 0, errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return t.RowsAffected, errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) MarkConversationMessageAsReadDB(ctx context.Context, conversationID string, msgIDs []string) (rowsAffected int64, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var msgs []*model_struct.LocalChatLog
if err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id in ? AND send_id != ?", msgIDs, d.loginUserID).Find(&msgs).Error; err != nil {
return 0, errs.WrapMsg(err, "MarkConversationMessageAsReadDB failed")
}
for _, msg := range msgs {
var attachedInfo sdk_struct.AttachedInfoElem
utils.JsonStringToStruct(msg.AttachedInfo, &attachedInfo)
attachedInfo.HasReadTime = utils.GetCurrentTimestampByMill()
msg.IsRead = true
msg.AttachedInfo = utils.StructToJsonString(attachedInfo)
if err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id = ?", msg.ClientMsgID).Updates(msg).Error; err != nil {
log.ZError(ctx, "MarkConversationMessageAsReadDB failed", err, "msg", msg)
} else {
rowsAffected++
}
}
// t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id in ? AND send_id != ?", msgIDs, d.loginUserID).Update("is_read", constant.HasRead)
// if t.RowsAffected == 0 {
// return 0, errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
// }
return rowsAffected, nil
}
func (d *DataBase) MarkConversationAllMessageAsRead(ctx context.Context, conversationID string) (rowsAffected int64, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("send_id != ? AND is_read == ?", d.loginUserID, false).Update("is_read", constant.HasRead)
if t.RowsAffected == 0 {
return 0, errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return t.RowsAffected, errs.WrapMsg(t.Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) GetMessagesByClientMsgIDs(ctx context.Context, conversationID string, msgIDs []string) (msgs []*model_struct.LocalChatLog, err error) {
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("client_msg_id IN ?", msgIDs).Order("send_time DESC").Find(&msgs).Error, "GetMessagesByClientMsgIDs error")
return msgs, err
}
func (d *DataBase) GetMessagesBySeqs(ctx context.Context, conversationID string, seqs []int64) (msgs []*model_struct.LocalChatLog, err error) {
err = errs.WrapMsg(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Where("seq IN ?", seqs).Order("send_time DESC").Find(&msgs).Error, "GetMessagesBySeqs error")
return msgs, err
}
func (d *DataBase) GetConversationNormalMsgSeq(ctx context.Context, conversationID string) (int64, error) {
d.initChatLog(ctx, conversationID)
var seq int64
err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Select("IFNULL(max(seq),0)").Find(&seq).Error
return seq, errs.WrapMsg(err, "GetConversationNormalMsgSeq")
}
func (d *DataBase) GetConversationPeerNormalMsgSeq(ctx context.Context, conversationID string) (int64, error) {
var seq int64
err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(conversationID)).Select("IFNULL(max(seq),0)").Where("send_id != ?", d.loginUserID).Find(&seq).Error
return seq, errs.WrapMsg(err, "GetConversationPeerNormalMsgSeq")
}

View File

@@ -0,0 +1,120 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) GetMessageReactionExtension(ctx context.Context, msgID string) (result *model_struct.LocalChatLogReactionExtensions, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var l model_struct.LocalChatLogReactionExtensions
return &l, utils.Wrap(d.conn.WithContext(ctx).Where("client_msg_id = ?",
msgID).Take(&l).Error, "GetMessageReactionExtension failed")
}
func (d *DataBase) InsertMessageReactionExtension(ctx context.Context, messageReactionExtension *model_struct.LocalChatLogReactionExtensions) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(messageReactionExtension).Error, "InsertMessageReactionExtension failed")
}
func (d *DataBase) UpdateMessageReactionExtension(ctx context.Context, c *model_struct.LocalChatLogReactionExtensions) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateConversation failed")
}
// func (d *DataBase) GetAndUpdateMessageReactionExtension(ctx context.Context, msgID string, m map[string]*sdkws.KeyValue) error {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// var temp model_struct.LocalChatLogReactionExtensions
// err := d.conn.WithContext(ctx).Where("client_msg_id = ?",
// msgID).Take(&temp).Error
// if err != nil {
// temp.ClientMsgID = msgID
// temp.LocalReactionExtensions = []byte(utils.StructToJsonString(m))
// return d.conn.WithContext(ctx).Create(&temp).Error
// } else {
// oldKeyValue := make(map[string]*sdkws.KeyValue)
// err = json.Unmarshal(temp.LocalReactionExtensions, &oldKeyValue)
// if err != nil {
// log.Error("special handle", err.Error())
// }
// log.Warn("special handle", oldKeyValue)
// for k, newValue := range m {
// oldKeyValue[k] = newValue
// }
// temp.LocalReactionExtensions = []byte(utils.StructToJsonString(oldKeyValue))
// t := d.conn.WithContext(ctx).Updates(temp)
// if t.RowsAffected == 0 {
// return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
// }
// }
// return nil
// }
func (d *DataBase) DeleteMessageReactionExtension(ctx context.Context, msgID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
temp := model_struct.LocalChatLogReactionExtensions{ClientMsgID: msgID}
return d.conn.WithContext(ctx).Delete(&temp).Error
}
// func (d *DataBase) DeleteAndUpdateMessageReactionExtension(ctx context.Context, msgID string, m map[string]*sdkws.KeyValue) error {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// var temp model_struct.LocalChatLogReactionExtensions
// err := d.conn.WithContext(ctx).Where("client_msg_id = ?",
// msgID).Take(&temp).Error
// if err != nil {
// return err
// } else {
// oldKeyValue := make(map[string]*server_api_params.KeyValue)
// _ = json.Unmarshal(temp.LocalReactionExtensions, &oldKeyValue)
// for k := range m {
// if _, ok := oldKeyValue[k]; ok {
// delete(oldKeyValue, k)
// }
// }
// temp.LocalReactionExtensions = []byte(utils.StructToJsonString(oldKeyValue))
// t := d.conn.WithContext(ctx).Updates(temp)
// if t.RowsAffected == 0 {
// return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
// }
// }
// return nil
// }
// func (d *DataBase) GetMultipleMessageReactionExtension(ctx context.Context, msgIDList []string) (result []*model_struct.LocalChatLogReactionExtensions, err error) {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// var messageList []model_struct.LocalChatLogReactionExtensions
// err = utils.Wrap(d.conn.WithContext(ctx).Where("client_msg_id IN ?", msgIDList).Find(&messageList).Error, "GetMultipleMessageReactionExtension failed")
// for _, v := range messageList {
// v1 := v
// result = append(result, &v1)
// }
// return result, err
// }

View File

@@ -0,0 +1,383 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"gorm.io/gorm"
)
func (d *DataBase) GetConversationByUserID(ctx context.Context, userID string) (*model_struct.LocalConversation, error) {
var conversation model_struct.LocalConversation
err := utils.Wrap(d.conn.WithContext(ctx).Where("user_id=?", userID).Find(&conversation).Error, "GetConversationByUserID error")
return &conversation, err
}
func (d *DataBase) GetAllConversationListDB(ctx context.Context) ([]*model_struct.LocalConversation, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var conversationList []*model_struct.LocalConversation
err := utils.Wrap(d.conn.WithContext(ctx).Where("latest_msg_send_time > ?", 0).Order("case when is_pinned=1 then 0 else 1 end,max(latest_msg_send_time,draft_text_time) DESC").Find(&conversationList).Error,
"GetAllConversationList failed")
if err != nil {
return nil, err
}
return conversationList, err
}
func (d *DataBase) FindAllConversationConversationID(ctx context.Context) (conversationIDs []string, err error) {
return conversationIDs, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("latest_msg_send_time > ?", 0).Pluck("conversation_id", &conversationIDs).Error, "")
}
func (d *DataBase) GetHiddenConversationList(ctx context.Context) ([]*model_struct.LocalConversation, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var conversationList []model_struct.LocalConversation
err := utils.Wrap(d.conn.WithContext(ctx).Where("latest_msg_send_time = ?", 0).Find(&conversationList).Error,
"GetHiddenConversationList failed")
var transfer []*model_struct.LocalConversation
for _, v := range conversationList {
v1 := v
transfer = append(transfer, &v1)
}
return transfer, err
}
func (d *DataBase) GetAllConversations(ctx context.Context) ([]*model_struct.LocalConversation, error) {
var conversationList []*model_struct.LocalConversation
err := utils.Wrap(d.conn.WithContext(ctx).Find(&conversationList).Error, "GetAllConversations failed")
return conversationList, err
}
func (d *DataBase) GetAllConversationIDList(ctx context.Context) (result []string, err error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var c model_struct.LocalConversation
err = d.conn.WithContext(ctx).Model(&c).Pluck("conversation_id", &result).Error
return result, utils.Wrap(err, "GetAllConversationIDList failed ")
}
func (d *DataBase) GetAllSingleConversationIDList(ctx context.Context) (result []string, err error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var c model_struct.LocalConversation
err = d.conn.WithContext(ctx).Model(&c).Where("conversation_type = ?", constant.SingleChatType).Pluck("conversation_id", &result).Error
return result, utils.Wrap(err, "GetAllConversationIDList failed ")
}
func (d *DataBase) GetConversationListSplitDB(ctx context.Context, offset, count int) ([]*model_struct.LocalConversation, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var conversationList []model_struct.LocalConversation
err := utils.Wrap(d.conn.WithContext(ctx).Where("latest_msg_send_time > ?", 0).Order("case when is_pinned=1 then 0 else 1 end,max(latest_msg_send_time,draft_text_time) DESC").Offset(offset).Limit(count).Find(&conversationList).Error,
"GetFriendList failed")
var transfer []*model_struct.LocalConversation
for _, v := range conversationList {
v1 := v
transfer = append(transfer, &v1)
}
return transfer, err
}
func (d *DataBase) BatchInsertConversationList(ctx context.Context, conversationList []*model_struct.LocalConversation) error {
if conversationList == nil {
return nil
}
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(conversationList).Error, "BatchInsertConversationList failed")
}
func (d *DataBase) UpdateOrCreateConversations(ctx context.Context, conversationList []*model_struct.LocalConversation) error {
var conversationIDs []string
if err := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Pluck("conversation_id", &conversationIDs).Error; err != nil {
return err
}
var notExistConversations []*model_struct.LocalConversation
var existConversations []*model_struct.LocalConversation
for i, v := range conversationList {
if utils.IsContain(v.ConversationID, conversationIDs) {
existConversations = append(existConversations, v)
continue
} else {
notExistConversations = append(notExistConversations, conversationList[i])
}
}
if len(notExistConversations) > 0 {
if err := d.conn.WithContext(ctx).Create(notExistConversations).Error; err != nil {
return err
}
}
for _, v := range existConversations {
if err := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("conversation_id = ?", v.ConversationID).Updates(map[string]interface{}{"unread_count": v.UnreadCount}).Error; err != nil {
return err
}
}
return nil
}
func (d *DataBase) InsertConversation(ctx context.Context, conversationList *model_struct.LocalConversation) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(conversationList).Error, "InsertConversation failed")
}
func (d *DataBase) DeleteConversation(ctx context.Context, conversationID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Where("conversation_id = ?", conversationID).Delete(&model_struct.LocalConversation{}).Error, "DeleteConversation failed")
}
func (d *DataBase) GetConversation(ctx context.Context, conversationID string) (*model_struct.LocalConversation, error) {
var c model_struct.LocalConversation
return &c, utils.Wrap(d.conn.WithContext(ctx).Where("conversation_id = ?",
conversationID).Take(&c).Error, "GetConversation failed, conversationID: "+conversationID)
}
func (d *DataBase) UpdateConversation(ctx context.Context, c *model_struct.LocalConversation) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
d.conn.WithContext(ctx).Logger.LogMode(6)
t := d.conn.WithContext(ctx).Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateConversation failed")
}
func (d *DataBase) UpdateConversationForSync(ctx context.Context, c *model_struct.LocalConversation) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("conversation_id = ?", c.ConversationID).
Updates(map[string]interface{}{"recv_msg_opt": c.RecvMsgOpt, "is_pinned": c.IsPinned, "is_private_chat": c.IsPrivateChat,
"group_at_type": c.GroupAtType, "is_not_in_group": c.IsNotInGroup, "update_unread_count_time": c.UpdateUnreadCountTime, "ex": c.Ex, "attached_info": c.AttachedInfo,
"burn_duration": c.BurnDuration, "msg_destruct_time": c.MsgDestructTime, "is_msg_destruct": c.IsMsgDestruct})
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateConversation failed")
}
func (d *DataBase) BatchUpdateConversationList(ctx context.Context, conversationList []*model_struct.LocalConversation) error {
for _, v := range conversationList {
err := d.UpdateConversation(ctx, v)
if err != nil {
return utils.Wrap(err, "BatchUpdateConversationList failed")
}
}
return nil
}
func (d *DataBase) ConversationIfExists(ctx context.Context, conversationID string) (bool, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var count int64
t := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("conversation_id = ?",
conversationID).Count(&count)
if t.Error != nil {
return false, utils.Wrap(t.Error, "ConversationIfExists get failed")
}
if count != 1 {
return false, nil
} else {
return true, nil
}
}
// Reset the conversation is equivalent to deleting the conversation,
// and the GetAllConversation or GetConversationListSplit interface will no longer be obtained.
func (d *DataBase) ResetConversation(ctx context.Context, conversationID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalConversation{ConversationID: conversationID, UnreadCount: 0, LatestMsg: "", LatestMsgSendTime: 0, DraftText: "", DraftTextTime: 0}
t := d.conn.WithContext(ctx).Select("unread_count", "latest_msg", "latest_msg_send_time", "draft_text", "draft_text_time").Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "ResetConversation failed")
}
// ResetAllConversation Reset ALL conversation is equivalent to deleting the conversation,
// and the GetAllConversation or GetConversationListSplit interface will no longer be obtained.
func (d *DataBase) ResetAllConversation(ctx context.Context) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalConversation{UnreadCount: 0, LatestMsg: "", LatestMsgSendTime: 0, DraftText: "", DraftTextTime: 0}
t := d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Select("unread_count", "latest_msg", "latest_msg_send_time", "draft_text", "draft_text_time").Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "ResetConversation failed")
}
// Clear the conversation, which is used to delete the conversation history message and clear the conversation at the same time.
// The GetAllConversation or GetConversationListSplit interface can still be obtained,
// but there is no latest message.
func (d *DataBase) ClearConversation(ctx context.Context, conversationID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalConversation{ConversationID: conversationID, UnreadCount: 0, LatestMsg: "", DraftText: "", DraftTextTime: 0}
t := d.conn.WithContext(ctx).Select("unread_count", "latest_msg", "draft_text", "draft_text_time").Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "ClearConversation failed")
}
func (d *DataBase) SetConversationDraftDB(ctx context.Context, conversationID, draftText string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
nowTime := utils.GetCurrentTimestampByMill()
t := d.conn.WithContext(ctx).Exec("update local_conversations set draft_text=?,draft_text_time=?,latest_msg_send_time=case when latest_msg_send_time=? then ? else latest_msg_send_time end where conversation_id=?",
draftText, nowTime, 0, nowTime, conversationID)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "SetConversationDraft failed")
}
func (d *DataBase) RemoveConversationDraft(ctx context.Context, conversationID, draftText string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalConversation{ConversationID: conversationID, DraftText: draftText, DraftTextTime: 0}
t := d.conn.WithContext(ctx).Select("draft_text", "draft_text_time").Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "RemoveConversationDraft failed")
}
func (d *DataBase) UnPinConversation(ctx context.Context, conversationID string, isPinned int) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Exec("update local_conversations set is_pinned=?,draft_text_time=case when draft_text=? then ? else draft_text_time end where conversation_id=?",
isPinned, "", 0, conversationID)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UnPinConversation failed")
}
func (d *DataBase) UpdateColumnsConversation(ctx context.Context, conversationID string, args map[string]interface{}) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Model(model_struct.LocalConversation{ConversationID: conversationID}).Updates(args)
if t.RowsAffected == 0 {
return utils.Wrap(errs.ErrRecordNotFound, "no update")
}
return utils.Wrap(t.Error, "UpdateColumnsConversation failed")
}
func (d *DataBase) UpdateAllConversation(ctx context.Context, conversation *model_struct.LocalConversation) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
if conversation.ConversationID != "" {
return utils.Wrap(errors.New("not update all conversation"), "UpdateAllConversation failed")
}
t := d.conn.WithContext(ctx).Model(conversation).Updates(conversation)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateColumnsConversation failed")
}
func (d *DataBase) IncrConversationUnreadCount(ctx context.Context, conversationID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalConversation{ConversationID: conversationID}
t := d.conn.WithContext(ctx).Model(&c).Update("unread_count", gorm.Expr("unread_count+?", 1))
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "IncrConversationUnreadCount failed")
}
func (d *DataBase) GetTotalUnreadMsgCountDB(ctx context.Context) (totalUnreadCount int32, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var result []int64
err = d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("recv_msg_opt < ? and latest_msg_send_time > ?", constant.ReceiveNotNotifyMessage, 0).Pluck("unread_count", &result).Error
if err != nil {
return totalUnreadCount, utils.Wrap(errors.New("GetTotalUnreadMsgCount err"), "GetTotalUnreadMsgCount err")
}
for _, v := range result {
totalUnreadCount += int32(v)
}
return totalUnreadCount, nil
}
func (d *DataBase) SetMultipleConversationRecvMsgOpt(ctx context.Context, conversationIDList []string, opt int) (err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Model(&model_struct.LocalConversation{}).Where("conversation_id IN ?", conversationIDList).Updates(map[string]interface{}{"recv_msg_opt": opt})
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "SetMultipleConversationRecvMsgOpt failed")
}
func (d *DataBase) GetMultipleConversationDB(ctx context.Context, conversationIDList []string) (result []*model_struct.LocalConversation, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var conversationList []model_struct.LocalConversation
err = utils.Wrap(d.conn.WithContext(ctx).Where("conversation_id IN ?", conversationIDList).Find(&conversationList).Error, "GetMultipleConversation failed")
for _, v := range conversationList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) DecrConversationUnreadCount(ctx context.Context, conversationID string, count int64) (err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
tx := d.conn.WithContext(ctx).Begin()
c := model_struct.LocalConversation{ConversationID: conversationID}
t := tx.Model(&c).Update("unread_count", gorm.Expr("unread_count-?", count))
if t.Error != nil {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
if err := tx.Where("conversation_id = ?",
conversationID).Take(&c).Error; err != nil {
tx.Rollback()
return utils.Wrap(errors.New("get conversation err"), "")
}
if c.UnreadCount < 0 {
log.ZWarn(ctx, "decr unread count < 0", nil, "conversationID", conversationID, "count", count)
if t = tx.Model(&c).Update("unread_count", 0); t.Error != nil {
tx.Rollback()
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
}
tx.Commit()
return nil
}
func (d *DataBase) SearchConversations(ctx context.Context, searchParam string) ([]*model_struct.LocalConversation, error) {
// Define the search condition based on the searchParam
condition := fmt.Sprintf("show_name like %q ", "%"+searchParam+"%")
var conversationList []model_struct.LocalConversation
err := d.conn.WithContext(ctx).Where(condition).Order("latest_msg_send_time DESC").Find(&conversationList).Error
var transfer []*model_struct.LocalConversation
for _, v := range conversationList {
v1 := v // Create a copy to avoid referencing the loop variable
transfer = append(transfer, &v1)
}
return transfer, utils.Wrap(err, "SearchConversation failed ")
}

View File

@@ -0,0 +1,38 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) BatchInsertConversationUnreadMessageList(ctx context.Context, messageList []*model_struct.LocalConversationUnreadMessage) error {
if messageList == nil {
return nil
}
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(messageList).Error, "BatchInsertConversationUnreadMessageList failed")
}
func (d *DataBase) DeleteConversationUnreadMessageList(ctx context.Context, conversationID string, sendTime int64) int64 {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return d.conn.WithContext(ctx).Where("conversation_id = ? and send_time <= ?", conversationID, sendTime).Delete(&model_struct.LocalConversationUnreadMessage{}).RowsAffected
}

View File

@@ -0,0 +1,200 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"path/filepath"
"sync"
"time"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/openimsdk/openim-sdk-core/v3/version"
"github.com/openimsdk/tools/errs"
"github.com/openimsdk/tools/log"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type DataBase struct {
loginUserID string
dbDir string
conn *gorm.DB
mRWMutex sync.RWMutex
groupMtx sync.RWMutex
friendMtx sync.RWMutex
userMtx sync.RWMutex
versionMtx sync.RWMutex
superGroupMtx sync.RWMutex
}
func (d *DataBase) GetMultipleMessageReactionExtension(ctx context.Context, msgIDList []string) (result []*model_struct.LocalChatLogReactionExtensions, err error) {
// TODO implement me
panic("implement me")
}
func (d *DataBase) InitSuperLocalErrChatLog(ctx context.Context, groupID string) {
panic("implement me")
}
func (d *DataBase) InitSuperLocalChatLog(ctx context.Context, groupID string) {
panic("implement me")
}
func (d *DataBase) SetChatLogFailedStatus(ctx context.Context) {
panic("implement me")
}
func (d *DataBase) InitDB(ctx context.Context, userID string, dataDir string) error {
panic("implement me")
}
func (d *DataBase) Close(ctx context.Context) error {
dbConn, err := d.conn.WithContext(ctx).DB()
if err != nil {
return err
} else {
if dbConn != nil {
err := dbConn.Close()
if err != nil {
return err
}
}
}
return nil
}
func NewDataBase(ctx context.Context, loginUserID string, dbDir string, logLevel int) (*DataBase, error) {
dataBase := &DataBase{loginUserID: loginUserID, dbDir: dbDir}
err := dataBase.initDB(ctx, logLevel)
if err != nil {
return dataBase, utils.Wrap(err, "initDB failed "+dbDir)
}
return dataBase, nil
}
func (d *DataBase) initDB(ctx context.Context, logLevel int) error {
var zLogLevel logger.LogLevel
if d.loginUserID == "" {
return errors.New("no uid")
}
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
path := d.dbDir + "/OpenIM_" + constant.BigVersion + "_" + d.loginUserID + ".db"
dbFileName, err := filepath.Abs(path)
if err != nil {
return err
}
log.ZInfo(ctx, "sqlite", "path", dbFileName)
// slowThreshold := 500
// sqlLogger := log.NewSqlLogger(logger.LogLevel(sdk_struct.SvrConf.LogLevel), true, time.Duration(slowThreshold)*time.Millisecond)
if logLevel > 5 {
zLogLevel = logger.Info
} else {
zLogLevel = logger.Silent
}
db, err := gorm.Open(sqlite.Open(dbFileName), &gorm.Config{Logger: log.NewSqlLogger(zLogLevel, false, time.Millisecond*200)})
if err != nil {
return utils.Wrap(err, "open db failed "+dbFileName)
}
log.ZDebug(ctx, "open db success", "db", db, "dbFileName", dbFileName)
sqlDB, err := db.DB()
if err != nil {
return utils.Wrap(err, "get sql db failed")
}
sqlDB.SetConnMaxLifetime(time.Hour * 1)
sqlDB.SetMaxOpenConns(3)
sqlDB.SetMaxIdleConns(2)
sqlDB.SetConnMaxIdleTime(time.Minute * 10)
d.conn = db
// base
if err = db.AutoMigrate(&model_struct.LocalAppSDKVersion{}); err != nil {
return err
}
if err = d.versionDataMigrate(ctx); err != nil {
return err
}
//if err := db.Table(constant.SuperGroupTableName).AutoMigrate(superGroup); err != nil {
// return err
//}
return nil
}
func (d *DataBase) versionDataMigrate(ctx context.Context) error {
verModel, err := d.GetAppSDKVersion(ctx)
if errs.Unwrap(err) == gorm.ErrRecordNotFound {
err = d.conn.AutoMigrate(
&model_struct.LocalAppSDKVersion{},
&model_struct.LocalFriend{},
&model_struct.LocalFriendRequest{},
&model_struct.LocalGroup{},
&model_struct.LocalGroupMember{},
&model_struct.LocalGroupRequest{},
&model_struct.LocalErrChatLog{},
&model_struct.LocalUser{},
&model_struct.LocalBlack{},
&model_struct.LocalConversation{},
&model_struct.NotificationSeqs{},
&model_struct.LocalChatLog{},
&model_struct.LocalAdminGroupRequest{},
&model_struct.LocalWorkMomentsNotification{},
&model_struct.LocalWorkMomentsNotificationUnreadCount{},
&model_struct.TempCacheLocalChatLog{},
&model_struct.LocalChatLogReactionExtensions{},
&model_struct.LocalUpload{},
&model_struct.LocalStranger{},
&model_struct.LocalSendingMessages{},
&model_struct.LocalUserCommand{},
&model_struct.LocalVersionSync{},
)
if err != nil {
return err
}
err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: version.Version})
if err != nil {
return err
}
return nil
} else if err != nil {
return err
}
if verModel.Version != version.Version {
switch version.Version {
case "3.8.0":
d.conn.AutoMigrate(&model_struct.LocalAppSDKVersion{})
}
err = d.SetAppSDKVersion(ctx, &model_struct.LocalAppSDKVersion{Version: version.Version})
if err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,304 @@
// Copyright © 2023 OpenIM SDK. 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 db_interface
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
)
type GroupModel interface {
InsertGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error
DeleteGroup(ctx context.Context, groupID string) error
UpdateGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error
BatchInsertGroup(ctx context.Context, groupList []*model_struct.LocalGroup) error
DeleteAllGroup(ctx context.Context) error
GetJoinedGroupListDB(ctx context.Context) ([]*model_struct.LocalGroup, error)
GetGroups(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error)
GetGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error)
GetAllGroupInfoByGroupIDOrGroupName(ctx context.Context, keyword string, isSearchGroupID bool, isSearchGroupName bool) ([]*model_struct.LocalGroup, error)
AddMemberCount(ctx context.Context, groupID string) error
SubtractMemberCount(ctx context.Context, groupID string) error
GetJoinedWorkingGroupIDList(ctx context.Context) ([]string, error)
GetJoinedWorkingGroupList(ctx context.Context) ([]*model_struct.LocalGroup, error)
GetUserJoinedGroupIDs(ctx context.Context, userID string) ([]string, error)
InsertAdminGroupRequest(ctx context.Context, groupRequest *model_struct.LocalAdminGroupRequest) error
DeleteAdminGroupRequest(ctx context.Context, groupID, userID string) error
UpdateAdminGroupRequest(ctx context.Context, groupRequest *model_struct.LocalAdminGroupRequest) error
GetAdminGroupApplication(ctx context.Context) ([]*model_struct.LocalAdminGroupRequest, error)
InsertGroupRequest(ctx context.Context, groupRequest *model_struct.LocalGroupRequest) error
DeleteGroupRequest(ctx context.Context, groupID, userID string) error
UpdateGroupRequest(ctx context.Context, groupRequest *model_struct.LocalGroupRequest) error
GetSendGroupApplication(ctx context.Context) ([]*model_struct.LocalGroupRequest, error)
InsertSuperGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error
DeleteAllSuperGroup(ctx context.Context) error
GetSuperGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error)
UpdateSuperGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error
DeleteSuperGroup(ctx context.Context, groupID string) error
GetGroupMemberInfoByGroupIDUserID(ctx context.Context, groupID, userID string) (*model_struct.LocalGroupMember, error)
GetAllGroupMemberList(ctx context.Context) ([]model_struct.LocalGroupMember, error)
GetAllGroupMemberUserIDList(ctx context.Context) ([]model_struct.LocalGroupMember, error)
GetGroupMemberCount(ctx context.Context, groupID string) (int32, error)
GetGroupSomeMemberInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error)
GetGroupAdminID(ctx context.Context, groupID string) ([]string, error)
GetGroupMemberListByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error)
GetGroupMemberListSplit(ctx context.Context, groupID string, filter int32, offset, count int) ([]*model_struct.LocalGroupMember, error)
GetGroupMemberListByUserIDs(ctx context.Context, groupID string, filter int32, userIDs []string) ([]*model_struct.LocalGroupMember, error)
GetGroupMemberOwnerAndAdminDB(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error)
GetGroupMemberOwner(ctx context.Context, groupID string) (*model_struct.LocalGroupMember, error)
GetGroupMemberListSplitByJoinTimeFilter(ctx context.Context, groupID string, offset, count int, joinTimeBegin, joinTimeEnd int64, userIDList []string) ([]*model_struct.LocalGroupMember, error)
GetGroupOwnerAndAdminByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error)
GetGroupMemberUIDListByGroupID(ctx context.Context, groupID string) (result []string, err error)
GetGroupMemberAllGroupIDs(ctx context.Context) ([]string, error)
InsertGroupMember(ctx context.Context, groupMember *model_struct.LocalGroupMember) error
BatchInsertGroupMember(ctx context.Context, groupMemberList []*model_struct.LocalGroupMember) error
DeleteGroupMember(ctx context.Context, groupID, userID string) error
DeleteGroupAllMembers(ctx context.Context, groupID string) error
UpdateGroupMember(ctx context.Context, groupMember *model_struct.LocalGroupMember) error
UpdateGroupMemberField(ctx context.Context, groupID, userID string, args map[string]interface{}) error
GetGroupMemberInfoIfOwnerOrAdmin(ctx context.Context) ([]*model_struct.LocalGroupMember, error)
SearchGroupMembersDB(ctx context.Context, keyword string, groupID string, isSearchMemberNickname, isSearchUserID bool, offset, count int) (result []*model_struct.LocalGroupMember, err error)
}
type MessageModel interface {
BatchInsertMessageList(ctx context.Context, conversationID string, MessageList []*model_struct.LocalChatLog) error
// BatchInsertMessageListController(ctx context.Context, MessageList []*model_struct.LocalChatLog) error
InsertMessage(ctx context.Context, conversationID string, Message *model_struct.LocalChatLog) error
// InsertMessageController(ctx context.Context, message *model_struct.LocalChatLog) error
SearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error)
// SearchMessageByKeywordController(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error)
SearchMessageByContentType(ctx context.Context, contentType []int, conversationID string, startTime, endTime int64, offset, count int) (result []*model_struct.LocalChatLog, err error)
// SearchMessageByContentTypeController(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error)
SearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, conversationID string, keywordList []string, keywordListMatchType int, startTime, endTime int64) (result []*model_struct.LocalChatLog, err error)
MessageIfExists(ctx context.Context, ClientMsgID string) (bool, error)
IsExistsInErrChatLogBySeq(ctx context.Context, seq int64) bool
MessageIfExistsBySeq(ctx context.Context, seq int64) (bool, error)
GetMessage(ctx context.Context, conversationID, clientMsgID string) (*model_struct.LocalChatLog, error)
GetMessageBySeq(ctx context.Context, conversationID string, seq int64) (*model_struct.LocalChatLog, error)
// GetMessageController(ctx context.Context, conversationID, clientMsgID string) (*model_struct.LocalChatLog, error)
UpdateColumnsMessageList(ctx context.Context, clientMsgIDList []string, args map[string]interface{}) error
UpdateColumnsMessage(ctx context.Context, conversationID string, ClientMsgID string, args map[string]interface{}) error
// UpdateColumnsMessageController(ctx context.Context, ClientMsgID string, groupID string, sessionType int32, args map[string]interface{}) error
UpdateMessage(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error
UpdateMessageBySeq(ctx context.Context, conversationID string, c *model_struct.LocalChatLog) error
// UpdateMessageController(ctx context.Context, c *model_struct.LocalChatLog) error
DeleteAllMessage(ctx context.Context) error
UpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error
// UpdateMessageStatusBySourceIDController(ctx context.Context, sourceID string, status, sessionType int32) error
UpdateMessageTimeAndStatus(ctx context.Context, conversationID, clientMsgID string, serverMsgID string, sendTime int64, status int32) error
// UpdateMessageTimeAndStatusController(ctx context.Context, msg *sdk_struct.MsgStruct) error
GetMessageList(ctx context.Context, conversationID string, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error)
// GetMessageListController(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error)
GetMessageListNoTime(ctx context.Context, conversationID string, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error)
// GetMessageListNoTimeController(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error)
MarkConversationMessageAsReadDB(ctx context.Context, conversationID string, msgIDs []string) (rowsAffected int64, err error)
MarkConversationMessageAsReadBySeqs(ctx context.Context, conversationID string, seqs []int64) (rowsAffected int64, err error)
GetUnreadMessage(ctx context.Context, conversationID string) (result []*model_struct.LocalChatLog, err error)
MarkConversationAllMessageAsRead(ctx context.Context, conversationID string) (rowsAffected int64, err error)
GetMessagesByClientMsgIDs(ctx context.Context, conversationID string, msgIDs []string) (result []*model_struct.LocalChatLog, err error)
GetMessagesBySeqs(ctx context.Context, conversationID string, seqs []int64) (result []*model_struct.LocalChatLog, err error)
GetConversationNormalMsgSeq(ctx context.Context, conversationID string) (int64, error)
GetConversationPeerNormalMsgSeq(ctx context.Context, conversationID string) (int64, error)
GetTestMessage(ctx context.Context, seq uint32) (*model_struct.LocalChatLog, error)
UpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error
UpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error
// UpdateMsgSenderFaceURLAndSenderNicknameController(ctx context.Context, sendID, faceURL, nickname string, sessionType int) error
UpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, conversationID, sendID, faceURL, nickname string) error
GetMsgSeqByClientMsgID(ctx context.Context, clientMsgID string) (uint32, error)
// GetMsgSeqByClientMsgIDController(ctx context.Context, m *sdk_struct.MsgStruct) (uint32, error)
GetMsgSeqListByGroupID(ctx context.Context, groupID string) ([]uint32, error)
GetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error)
GetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error)
InitSuperLocalErrChatLog(ctx context.Context, groupID string)
SuperBatchInsertExceptionMsg(ctx context.Context, MessageList []*model_struct.LocalErrChatLog, groupID string) error
GetAbnormalMsgSeq(ctx context.Context) (int64, error)
GetAbnormalMsgSeqList(ctx context.Context) ([]int64, error)
BatchInsertExceptionMsg(ctx context.Context, MessageList []*model_struct.LocalErrChatLog) error
GetConversationAbnormalMsgSeq(ctx context.Context, groupID string) (int64, error)
BatchInsertTempCacheMessageList(ctx context.Context, MessageList []*model_struct.TempCacheLocalChatLog) error
InsertTempCacheMessage(ctx context.Context, Message *model_struct.TempCacheLocalChatLog) error
InitSuperLocalChatLog(ctx context.Context, groupID string)
SuperGroupBatchInsertMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog, groupID string) error
SuperGroupInsertMessage(ctx context.Context, Message *model_struct.LocalChatLog, groupID string) error
SuperGroupDeleteAllMessage(ctx context.Context, groupID string) error
DeleteConversationAllMessages(ctx context.Context, conversationID string) error
MarkDeleteConversationAllMessages(ctx context.Context, conversationID string) error
SuperGroupSearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error)
// SuperGroupSearchMessageByContentType(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error)
SuperGroupSearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64, groupID string) (result []*model_struct.LocalChatLog, err error)
SuperGroupBatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error
SuperGroupMessageIfExists(ctx context.Context, ClientMsgID string) (bool, error)
SuperGroupIsExistsInErrChatLogBySeq(ctx context.Context, seq int64) bool
SuperGroupMessageIfExistsBySeq(ctx context.Context, seq int64) (bool, error)
SuperGroupGetMessage(ctx context.Context, msg *sdk_struct.MsgStruct) (*model_struct.LocalChatLog, error)
SuperGroupGetAllUnDeleteMessageSeqList(ctx context.Context) ([]uint32, error)
SuperGroupUpdateColumnsMessage(ctx context.Context, ClientMsgID, groupID string, args map[string]interface{}) error
SuperGroupUpdateMessage(ctx context.Context, c *model_struct.LocalChatLog) error
SuperGroupUpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error
SuperGroupUpdateMessageTimeAndStatus(ctx context.Context, msg *sdk_struct.MsgStruct) error
SuperGroupGetMessageList(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error)
SuperGroupGetMessageListNoTime(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error)
SuperGroupGetSendingMessageList(ctx context.Context, groupID string) (result []*model_struct.LocalChatLog, err error)
SuperGroupUpdateGroupMessageHasRead(ctx context.Context, msgIDList []string, groupID string) error
// SuperGroupUpdateGroupMessageFields(ctx context.Context, msgIDList []string, groupID string, args map[string]interface{}) error
SuperGroupUpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error
SuperGroupUpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error
SuperGroupUpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, sendID, faceURL, nickname string, sessionType int, groupID string) error
SuperGroupGetMsgSeqByClientMsgID(ctx context.Context, clientMsgID string, groupID string) (uint32, error)
SuperGroupGetMsgSeqListByGroupID(ctx context.Context, groupID string) ([]uint32, error)
SuperGroupGetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error)
SuperGroupGetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error)
GetAlreadyExistSeqList(ctx context.Context, conversationID string, lostSeqList []int64) (seqList []int64, err error)
BatchInsertConversationUnreadMessageList(ctx context.Context, messageList []*model_struct.LocalConversationUnreadMessage) error
DeleteConversationUnreadMessageList(ctx context.Context, conversationID string, sendTime int64) int64
DeleteConversationMsgs(ctx context.Context, conversationID string, msgIDs []string) error
// DeleteConversationMsgsBySeqs(ctx context.Context, conversationID string, seqs []int64) error
SetNotificationSeq(ctx context.Context, conversationID string, seq int64) error
GetNotificationAllSeqs(ctx context.Context) ([]*model_struct.NotificationSeqs, error)
}
type ConversationModel interface {
GetConversationByUserID(ctx context.Context, userID string) (*model_struct.LocalConversation, error)
GetAllConversationListDB(ctx context.Context) ([]*model_struct.LocalConversation, error)
GetHiddenConversationList(ctx context.Context) ([]*model_struct.LocalConversation, error)
GetAllConversations(ctx context.Context) ([]*model_struct.LocalConversation, error)
GetAllSingleConversationIDList(ctx context.Context) (result []string, err error)
GetAllConversationIDList(ctx context.Context) (result []string, err error)
GetConversationListSplitDB(ctx context.Context, offset, count int) ([]*model_struct.LocalConversation, error)
BatchInsertConversationList(ctx context.Context, conversationList []*model_struct.LocalConversation) error
UpdateOrCreateConversations(ctx context.Context, conversationList []*model_struct.LocalConversation) error
InsertConversation(ctx context.Context, conversationList *model_struct.LocalConversation) error
DeleteConversation(ctx context.Context, conversationID string) error
GetConversation(ctx context.Context, conversationID string) (*model_struct.LocalConversation, error)
UpdateConversation(ctx context.Context, c *model_struct.LocalConversation) error
UpdateConversationForSync(ctx context.Context, c *model_struct.LocalConversation) error
BatchUpdateConversationList(ctx context.Context, conversationList []*model_struct.LocalConversation) error
ConversationIfExists(ctx context.Context, conversationID string) (bool, error)
ResetConversation(ctx context.Context, conversationID string) error
ResetAllConversation(ctx context.Context) error
ClearConversation(ctx context.Context, conversationID string) error
SetConversationDraftDB(ctx context.Context, conversationID, draftText string) error
RemoveConversationDraft(ctx context.Context, conversationID, draftText string) error
UnPinConversation(ctx context.Context, conversationID string, isPinned int) error
UpdateColumnsConversation(ctx context.Context, conversationID string, args map[string]interface{}) error
UpdateAllConversation(ctx context.Context, conversation *model_struct.LocalConversation) error
IncrConversationUnreadCount(ctx context.Context, conversationID string) error
DecrConversationUnreadCount(ctx context.Context, conversationID string, count int64) (err error)
GetTotalUnreadMsgCountDB(ctx context.Context) (totalUnreadCount int32, err error)
SetMultipleConversationRecvMsgOpt(ctx context.Context, conversationIDList []string, opt int) (err error)
GetMultipleConversationDB(ctx context.Context, conversationIDList []string) (result []*model_struct.LocalConversation, err error)
SearchAllMessageByContentType(ctx context.Context, conversationID string, contentType int) ([]*model_struct.LocalChatLog, error)
SuperGroupSearchAllMessageByContentType(ctx context.Context, superGroupID string, contentType int32) ([]*model_struct.LocalChatLog, error)
SearchConversations(ctx context.Context, searchParam string) ([]*model_struct.LocalConversation, error)
}
type UserModel interface {
GetLoginUser(ctx context.Context, userID string) (*model_struct.LocalUser, error)
UpdateLoginUser(ctx context.Context, user *model_struct.LocalUser) error
UpdateLoginUserByMap(ctx context.Context, user *model_struct.LocalUser, args map[string]interface{}) error
InsertLoginUser(ctx context.Context, user *model_struct.LocalUser) error
GetStrangerInfo(ctx context.Context, userIDs []string) ([]*model_struct.LocalStranger, error)
SetStrangerInfo(ctx context.Context, localStrangerList []*model_struct.LocalStranger) error
ProcessUserCommandAdd(ctx context.Context, command *model_struct.LocalUserCommand) error
ProcessUserCommandUpdate(ctx context.Context, command *model_struct.LocalUserCommand) error
ProcessUserCommandDelete(ctx context.Context, command *model_struct.LocalUserCommand) error
ProcessUserCommandGetAll(ctx context.Context) ([]*model_struct.LocalUserCommand, error)
}
type FriendModel interface {
InsertFriend(ctx context.Context, friend *model_struct.LocalFriend) error
DeleteFriendDB(ctx context.Context, friendUserID string) error
GetFriendListCount(ctx context.Context) (int64, error)
UpdateFriend(ctx context.Context, friend *model_struct.LocalFriend) error
GetAllFriendList(ctx context.Context) ([]*model_struct.LocalFriend, error)
GetPageFriendList(ctx context.Context, offset, count int) ([]*model_struct.LocalFriend, error)
BatchInsertFriend(ctx context.Context, friendList []*model_struct.LocalFriend) error
DeleteAllFriend(ctx context.Context) error
SearchFriendList(ctx context.Context, keyword string, isSearchUserID, isSearchNickname, isSearchRemark bool) ([]*model_struct.LocalFriend, error)
GetFriendInfoByFriendUserID(ctx context.Context, FriendUserID string) (*model_struct.LocalFriend, error)
GetFriendInfoList(ctx context.Context, friendUserIDList []string) ([]*model_struct.LocalFriend, error)
InsertFriendRequest(ctx context.Context, friendRequest *model_struct.LocalFriendRequest) error
DeleteFriendRequestBothUserID(ctx context.Context, fromUserID, toUserID string) error
UpdateFriendRequest(ctx context.Context, friendRequest *model_struct.LocalFriendRequest) error
GetRecvFriendApplication(ctx context.Context) ([]*model_struct.LocalFriendRequest, error)
GetSendFriendApplication(ctx context.Context) ([]*model_struct.LocalFriendRequest, error)
GetFriendApplicationByBothID(ctx context.Context, fromUserID, toUserID string) (*model_struct.LocalFriendRequest, error)
GetBothFriendReq(ctx context.Context, fromUserID, toUserID string) ([]*model_struct.LocalFriendRequest, error)
UpdateColumnsFriend(ctx context.Context, friendIDs []string, args map[string]interface{}) error
GetBlackListDB(ctx context.Context) ([]*model_struct.LocalBlack, error)
GetBlackListUserID(ctx context.Context) (blackListUid []string, err error)
GetBlackInfoByBlockUserID(ctx context.Context, blockUserID string) (*model_struct.LocalBlack, error)
GetBlackInfoList(ctx context.Context, blockUserIDList []string) ([]*model_struct.LocalBlack, error)
InsertBlack(ctx context.Context, black *model_struct.LocalBlack) error
UpdateBlack(ctx context.Context, black *model_struct.LocalBlack) error
DeleteBlack(ctx context.Context, blockUserID string) error
}
type ReactionModel interface {
GetMessageReactionExtension(ctx context.Context, msgID string) (result *model_struct.LocalChatLogReactionExtensions, err error)
InsertMessageReactionExtension(ctx context.Context, messageReactionExtension *model_struct.LocalChatLogReactionExtensions) error
UpdateMessageReactionExtension(ctx context.Context, c *model_struct.LocalChatLogReactionExtensions) error
// GetAndUpdateMessageReactionExtension(ctx context.Context, msgID string, m map[string]*sdkws.KeyValue) error
// DeleteAndUpdateMessageReactionExtension(ctx context.Context, msgID string, m map[string]*sdkws.KeyValue) error
GetMultipleMessageReactionExtension(ctx context.Context, msgIDList []string) (result []*model_struct.LocalChatLogReactionExtensions, err error)
DeleteMessageReactionExtension(ctx context.Context, msgID string) error
}
type S3Model interface {
GetUpload(ctx context.Context, partHash string) (*model_struct.LocalUpload, error)
InsertUpload(ctx context.Context, upload *model_struct.LocalUpload) error
DeleteUpload(ctx context.Context, partHash string) error
UpdateUpload(ctx context.Context, upload *model_struct.LocalUpload) error
DeleteExpireUpload(ctx context.Context) error
}
type SendingMessagesModel interface {
InsertSendingMessage(ctx context.Context, message *model_struct.LocalSendingMessages) error
DeleteSendingMessage(ctx context.Context, conversationID, clientMsgID string) error
GetAllSendingMessages(ctx context.Context) (friendRequests []*model_struct.LocalSendingMessages, err error)
}
type VersionSyncModel interface {
GetVersionSync(ctx context.Context, tableName, entityID string) (*model_struct.LocalVersionSync, error)
SetVersionSync(ctx context.Context, version *model_struct.LocalVersionSync) error
DeleteVersionSync(ctx context.Context, tableName, entityID string) error
}
type AppSDKVersion interface {
GetAppSDKVersion(ctx context.Context) (*model_struct.LocalAppSDKVersion, error)
SetAppSDKVersion(ctx context.Context, version *model_struct.LocalAppSDKVersion) error
}
type DataBase interface {
Close(ctx context.Context) error
InitDB(ctx context.Context, userID string, dataDir string) error
GroupModel
MessageModel
ConversationModel
UserModel
FriendModel
ReactionModel
S3Model
SendingMessagesModel
VersionSyncModel
AppSDKVersion
}

View File

@@ -0,0 +1,87 @@
// Copyright © 2023 OpenIM SDK. 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 db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/wasm/exec"
"github.com/openimsdk/openim-sdk-core/v3/wasm/indexdb"
)
var ErrType = errors.New("from javascript data type err")
type IndexDB struct {
*indexdb.LocalUsers
*indexdb.LocalConversations
*indexdb.LocalChatLogs
*indexdb.LocalSuperGroupChatLogs
*indexdb.LocalSuperGroup
*indexdb.LocalConversationUnreadMessages
*indexdb.LocalGroups
*indexdb.LocalGroupMember
*indexdb.LocalCacheMessage
*indexdb.FriendRequest
*indexdb.Black
*indexdb.Friend
*indexdb.LocalGroupRequest
*indexdb.LocalChatLogReactionExtensions
*indexdb.NotificationSeqs
*indexdb.LocalUpload
*indexdb.LocalStrangers
*indexdb.LocalSendingMessages
*indexdb.LocalUserCommand
loginUserID string
}
func (i IndexDB) Close(ctx context.Context) error {
_, err := exec.Exec()
return err
}
func (i IndexDB) InitDB(ctx context.Context, userID string, dataDir string) error {
_, err := exec.Exec(userID, dataDir)
return err
}
func NewDataBase(ctx context.Context, loginUserID string, dbDir string, logLevel int) (*IndexDB, error) {
i := &IndexDB{
LocalUsers: indexdb.NewLocalUsers(),
LocalConversations: indexdb.NewLocalConversations(),
LocalChatLogs: indexdb.NewLocalChatLogs(loginUserID),
LocalSuperGroupChatLogs: indexdb.NewLocalSuperGroupChatLogs(),
LocalSuperGroup: indexdb.NewLocalSuperGroup(),
LocalConversationUnreadMessages: indexdb.NewLocalConversationUnreadMessages(),
LocalGroups: indexdb.NewLocalGroups(),
LocalGroupMember: indexdb.NewLocalGroupMember(),
LocalCacheMessage: indexdb.NewLocalCacheMessage(),
FriendRequest: indexdb.NewFriendRequest(loginUserID),
Black: indexdb.NewBlack(loginUserID),
Friend: indexdb.NewFriend(loginUserID),
LocalGroupRequest: indexdb.NewLocalGroupRequest(),
LocalChatLogReactionExtensions: indexdb.NewLocalChatLogReactionExtensions(),
NotificationSeqs: indexdb.NewNotificationSeqs(),
LocalUpload: indexdb.NewLocalUpload(),
LocalStrangers: indexdb.NewLocalStrangers(),
LocalSendingMessages: indexdb.NewLocalSendingMessages(),
LocalUserCommand: indexdb.NewLocalUserCommand(),
loginUserID: loginUserID,
}
err := i.InitDB(ctx, loginUserID, dbDir)
if err != nil {
return nil, err
}
return i, nil
}

View File

@@ -0,0 +1,77 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) initSuperLocalErrChatLog(ctx context.Context, groupID string) {
if !d.conn.WithContext(ctx).Migrator().HasTable(utils.GetErrTableName(groupID)) {
d.conn.WithContext(ctx).Table(utils.GetErrTableName(groupID)).AutoMigrate(&model_struct.LocalErrChatLog{})
}
}
func (d *DataBase) SuperBatchInsertExceptionMsg(ctx context.Context, MessageList []*model_struct.LocalErrChatLog, groupID string) error {
if MessageList == nil {
return nil
}
d.initSuperLocalErrChatLog(ctx, groupID)
return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(MessageList).Error, "BatchInsertMessageList failed")
}
func (d *DataBase) GetAbnormalMsgSeq(ctx context.Context) (int64, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seq int64
err := d.conn.WithContext(ctx).Model(model_struct.LocalErrChatLog{}).Select("IFNULL(max(seq),0)").Find(&seq).Error
return seq, utils.Wrap(err, "GetAbnormalMsgSeq")
}
func (d *DataBase) GetAbnormalMsgSeqList(ctx context.Context) ([]int64, error) {
var seqList []int64
err := d.conn.WithContext(ctx).Model(model_struct.LocalErrChatLog{}).Select("seq").Find(&seqList).Error
return seqList, utils.Wrap(err, "GetAbnormalMsgSeqList")
}
func (d *DataBase) BatchInsertExceptionMsg(ctx context.Context, messageList []*model_struct.LocalErrChatLog) error {
if messageList == nil {
return nil
}
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(messageList).Error, "BatchInsertMessageList failed")
}
func (d *DataBase) BatchInsertExceptionMsgController(ctx context.Context, messageList []*model_struct.LocalErrChatLog) error {
if len(messageList) == 0 {
return nil
}
switch messageList[len(messageList)-1].SessionType {
case constant.SuperGroupChatType:
return d.SuperBatchInsertExceptionMsg(ctx, messageList, messageList[len(messageList)-1].RecvID)
default:
return d.BatchInsertExceptionMsg(ctx, messageList)
}
}
func (d *DataBase) GetConversationAbnormalMsgSeq(ctx context.Context, conversationID string) (int64, error) {
var seq int64
if !d.conn.WithContext(ctx).Migrator().HasTable(utils.GetErrTableName(conversationID)) {
return 0, nil
}
err := d.conn.WithContext(ctx).Table(utils.GetErrTableName(conversationID)).Select("IFNULL(max(seq),0)").Find(&seq).Error
return seq, utils.Wrap(err, "GetConversationNormalMsgSeq")
}

View File

@@ -0,0 +1,139 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"fmt"
"gorm.io/gorm"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) InsertFriend(ctx context.Context, friend *model_struct.LocalFriend) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(friend).Error, "InsertFriend failed")
}
func (d *DataBase) DeleteFriendDB(ctx context.Context, friendUserID string) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id=? and friend_user_id=?", d.loginUserID, friendUserID).Delete(&model_struct.LocalFriend{}).Error, "DeleteFriend failed")
}
func (d *DataBase) GetFriendListCount(ctx context.Context) (int64, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var count int64
return count, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Count(&count).Error, "GetFriendListCount failed")
}
func (d *DataBase) UpdateFriend(ctx context.Context, friend *model_struct.LocalFriend) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
t := d.conn.WithContext(ctx).Model(friend).Select("*").Updates(*friend)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.Wrap(t.Error)
}
func (d *DataBase) GetAllFriendList(ctx context.Context) ([]*model_struct.LocalFriend, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendList []*model_struct.LocalFriend
return friendList, errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ?", d.loginUserID).Find(&friendList).Error,
"GetFriendList failed")
}
func (d *DataBase) GetPageFriendList(ctx context.Context, offset, count int) ([]*model_struct.LocalFriend, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendList []*model_struct.LocalFriend
err := errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ?", d.loginUserID).Offset(offset).Limit(count).Order("name").Find(&friendList).Error,
"GetFriendList failed")
return friendList, err
}
func (d *DataBase) BatchInsertFriend(ctx context.Context, friendList []*model_struct.LocalFriend) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
if friendList == nil {
return errs.New("nil").Wrap()
}
return errs.WrapMsg(d.conn.WithContext(ctx).Create(friendList).Error, "BatchInsertFriendList failed")
}
func (d *DataBase) DeleteAllFriend(ctx context.Context) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&model_struct.LocalFriend{}).Error, "DeleteAllFriend failed")
}
func (d *DataBase) SearchFriendList(ctx context.Context, keyword string, isSearchUserID, isSearchNickname, isSearchRemark bool) ([]*model_struct.LocalFriend, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var count int
var friendList []*model_struct.LocalFriend
var condition string
if isSearchUserID {
condition = fmt.Sprintf("friend_user_id like %q ", "%"+keyword+"%")
count++
}
if isSearchNickname {
if count > 0 {
condition += "or "
}
condition += fmt.Sprintf("name like %q ", "%"+keyword+"%")
count++
}
if isSearchRemark {
if count > 0 {
condition += "or "
}
condition += fmt.Sprintf("remark like %q ", "%"+keyword+"%")
}
err := d.conn.WithContext(ctx).Where(condition).Order("create_time DESC").Find(&friendList).Error
return friendList, errs.WrapMsg(err, "SearchFriendList failed")
}
func (d *DataBase) GetFriendInfoByFriendUserID(ctx context.Context, FriendUserID string) (*model_struct.LocalFriend, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friend model_struct.LocalFriend
return &friend, errs.WrapMsg(d.conn.WithContext(ctx).Where("owner_user_id = ? AND friend_user_id = ?",
d.loginUserID, FriendUserID).Take(&friend).Error, "GetFriendInfoByFriendUserID failed")
}
func (d *DataBase) GetFriendInfoList(ctx context.Context, friendUserIDList []string) ([]*model_struct.LocalFriend, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendList []*model_struct.LocalFriend
err := errs.WrapMsg(d.conn.WithContext(ctx).Where("friend_user_id IN ?", friendUserIDList).Find(&friendList).Error, "GetFriendInfoListByFriendUserID failed")
return friendList, err
}
func (d *DataBase) UpdateColumnsFriend(ctx context.Context, friendIDs []string, args map[string]interface{}) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalFriend{}).Where("friend_user_id IN ?", friendIDs).Updates(args).Error, "UpdateColumnsFriend failed")
}

View File

@@ -0,0 +1,76 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) InsertFriendRequest(ctx context.Context, friendRequest *model_struct.LocalFriendRequest) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(friendRequest).Error, "InsertFriendRequest failed")
}
func (d *DataBase) DeleteFriendRequestBothUserID(ctx context.Context, fromUserID, toUserID string) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Where("from_user_id=? and to_user_id=?", fromUserID, toUserID).Delete(&model_struct.LocalFriendRequest{}).Error, "DeleteFriendRequestBothUserID failed")
}
func (d *DataBase) UpdateFriendRequest(ctx context.Context, friendRequest *model_struct.LocalFriendRequest) error {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
t := d.conn.WithContext(ctx).Model(friendRequest).Select("*").Updates(*friendRequest)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.Wrap(t.Error)
}
func (d *DataBase) GetRecvFriendApplication(ctx context.Context) ([]*model_struct.LocalFriendRequest, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendRequestList []*model_struct.LocalFriendRequest
return friendRequestList, errs.WrapMsg(d.conn.WithContext(ctx).Where("to_user_id = ?", d.loginUserID).Order("create_time DESC").Find(&friendRequestList).Error, "GetRecvFriendApplication failed")
}
func (d *DataBase) GetSendFriendApplication(ctx context.Context) ([]*model_struct.LocalFriendRequest, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendRequestList []*model_struct.LocalFriendRequest
return friendRequestList, errs.WrapMsg(d.conn.WithContext(ctx).Where("from_user_id = ?", d.loginUserID).Order("create_time DESC").Find(&friendRequestList).Error, "GetSendFriendApplication failed")
}
func (d *DataBase) GetFriendApplicationByBothID(ctx context.Context, fromUserID, toUserID string) (*model_struct.LocalFriendRequest, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendRequest model_struct.LocalFriendRequest
return &friendRequest, errs.WrapMsg(d.conn.WithContext(ctx).Where("from_user_id = ? AND to_user_id = ?", fromUserID, toUserID).Take(&friendRequest).Error, "GetFriendApplicationByBothID failed")
}
func (d *DataBase) GetBothFriendReq(ctx context.Context, fromUserID, toUserID string) (friendRequests []*model_struct.LocalFriendRequest, err error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
return friendRequests, errs.WrapMsg(d.conn.WithContext(ctx).Where("(from_user_id = ? AND to_user_id = ?) OR (from_user_id = ? AND to_user_id = ?)", fromUserID, toUserID, toUserID, fromUserID).Find(&friendRequests).Error, "GetFriendApplicationByBothID failed")
}

View File

@@ -0,0 +1,307 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) GetGroupMemberInfoByGroupIDUserID(ctx context.Context, groupID, userID string) (*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMember model_struct.LocalGroupMember
return &groupMember, errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id = ? AND user_id = ?",
groupID, userID).Take(&groupMember).Error, "GetGroupMemberInfoByGroupIDUserID failed")
}
func (d *DataBase) GetAllGroupMemberList(ctx context.Context) ([]model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []model_struct.LocalGroupMember
return groupMemberList, errs.WrapMsg(d.conn.WithContext(ctx).Find(&groupMemberList).Error, "GetAllGroupMemberList failed")
}
func (d *DataBase) GetAllGroupMemberUserIDList(ctx context.Context) ([]model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []model_struct.LocalGroupMember
return groupMemberList, errs.WrapMsg(d.conn.WithContext(ctx).Find(&groupMemberList).Error, "GetAllGroupMemberList failed")
}
func (d *DataBase) GetGroupMemberCount(ctx context.Context, groupID string) (int32, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var count int64
err := d.conn.WithContext(ctx).Model(&model_struct.LocalGroupMember{}).Where("group_id = ? ", groupID).Count(&count).Error
return int32(count), errs.WrapMsg(err, "GetGroupMemberCount failed")
}
func (d *DataBase) GetGroupSomeMemberInfo(ctx context.Context, groupID string, userIDList []string) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
err := d.conn.WithContext(ctx).Where("group_id = ? And user_id IN ? ", groupID, userIDList).Find(&groupMemberList).Error
return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ")
}
func (d *DataBase) GetGroupAdminID(ctx context.Context, groupID string) ([]string, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var adminIDList []string
return adminIDList, errs.WrapMsg(d.conn.WithContext(ctx).Model(&model_struct.LocalGroupMember{}).Select("user_id").Where("group_id = ? And role_level = ?", groupID, constant.GroupAdmin).Find(&adminIDList).Error, "")
}
func (d *DataBase) GetGroupMemberListByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
err := d.conn.WithContext(ctx).Where("group_id = ? ", groupID).Find(&groupMemberList).Error
return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ")
}
func (d *DataBase) GetGroupMemberListByUserIDs(ctx context.Context, groupID string, filter int32, userIDs []string) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
var err error
switch filter {
case constant.GroupFilterAll:
err = d.conn.WithContext(ctx).Where("group_id = ? AND user_id IN ?", groupID, userIDs).Order("role_level DESC, join_time ASC").Find(&groupMemberList).Error
case constant.GroupFilterOwner:
err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOwner, userIDs).Find(&groupMemberList).Error
case constant.GroupFilterAdmin:
err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupAdmin, userIDs).Find(&groupMemberList).Error
case constant.GroupFilterOrdinaryUsers:
err = d.conn.WithContext(ctx).Where("group_id = ? AND role_level = ? AND user_id IN ?", groupID, constant.GroupOrdinaryUsers, userIDs).Find(&groupMemberList).Error
case constant.GroupFilterAdminAndOrdinaryUsers:
err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupAdmin, constant.GroupOrdinaryUsers, userIDs).Find(&groupMemberList).Error
case constant.GroupFilterOwnerAndAdmin:
err = d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? OR role_level = ?) AND user_id IN ?", groupID, constant.GroupOwner, constant.GroupAdmin, userIDs).Find(&groupMemberList).Error
default:
return nil, errs.New("filter args failed.", "filter", filter).Wrap()
}
return groupMemberList, errs.Wrap(err)
}
func (d *DataBase) GetGroupMemberListSplit(ctx context.Context, groupID string, filter int32, offset, count int) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
var err error
switch filter {
case constant.GroupFilterAll:
err = d.conn.WithContext(ctx).Where("group_id = ?", groupID).Order("role_level DESC,join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
case constant.GroupFilterOwner:
err = d.conn.WithContext(ctx).Where("group_id = ? And role_level = ?", groupID, constant.GroupOwner).Offset(offset).Limit(count).Find(&groupMemberList).Error
case constant.GroupFilterAdmin:
err = d.conn.WithContext(ctx).Where("group_id = ? And role_level = ?", groupID, constant.GroupAdmin).Order("join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
case constant.GroupFilterOrdinaryUsers:
err = d.conn.WithContext(ctx).Where("group_id = ? And role_level = ?", groupID, constant.GroupOrdinaryUsers).Order("join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
case constant.GroupFilterAdminAndOrdinaryUsers:
err = d.conn.WithContext(ctx).Where("group_id = ? And (role_level = ? or role_level = ?)", groupID, constant.GroupAdmin, constant.GroupOrdinaryUsers).Order("role_level DESC,join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
case constant.GroupFilterOwnerAndAdmin:
err = d.conn.WithContext(ctx).Where("group_id = ? And (role_level = ? or role_level = ?)", groupID, constant.GroupOwner, constant.GroupAdmin).Order("role_level DESC,join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
default:
return nil, errs.New("filter args failed", "filter", filter).Wrap()
}
return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListSplit failed ")
}
func (d *DataBase) GetGroupMemberOwnerAndAdminDB(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
err := d.conn.WithContext(ctx).Where("group_id = ? And (role_level = ? OR role_level = ?)", groupID, constant.GroupOwner, constant.GroupAdmin).Order("join_time DESC").Find(&groupMemberList).Error
return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListSplit failed ")
}
func (d *DataBase) GetGroupMemberOwner(ctx context.Context, groupID string) (*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMember model_struct.LocalGroupMember
err := d.conn.WithContext(ctx).Where("group_id = ? And role_level = ?", groupID, constant.GroupOwner).Find(&groupMember).Error
return &groupMember, errs.WrapMsg(err, "GetGroupMemberListSplit failed ")
}
func (d *DataBase) GetGroupMemberListSplitByJoinTimeFilter(ctx context.Context, groupID string, offset, count int, joinTimeBegin, joinTimeEnd int64, userIDList []string) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
var err error
if len(userIDList) == 0 {
err = d.conn.WithContext(ctx).Where("group_id = ? And join_time between ? and ? ", groupID, joinTimeBegin, joinTimeEnd).Order("join_time DESC").Offset(offset).Limit(count).Find(&groupMemberList).Error
} else {
err = d.conn.WithContext(ctx).Where("group_id = ? And join_time between ? and ? And user_id NOT IN ?", groupID, joinTimeBegin, joinTimeEnd, userIDList).Order("join_time DESC").Offset(offset).Limit(count).Find(&groupMemberList).Error
}
return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListSplitByJoinTimeFilter failed ")
}
func (d *DataBase) GetGroupOwnerAndAdminByGroupID(ctx context.Context, groupID string) ([]*model_struct.LocalGroupMember, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMemberList []*model_struct.LocalGroupMember
err := d.conn.WithContext(ctx).Where("group_id = ? AND (role_level = ? Or role_level = ?)", groupID, constant.GroupOwner, constant.GroupAdmin).Find(&groupMemberList).Error
return groupMemberList, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ")
}
func (d *DataBase) GetGroupMemberUIDListByGroupID(ctx context.Context, groupID string) (result []string, err error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var g model_struct.LocalGroupMember
g.GroupID = groupID
err = d.conn.WithContext(ctx).Model(&g).Where("group_id = ?", groupID).Pluck("user_id", &result).Error
return result, errs.WrapMsg(err, "GetGroupMemberListByGroupID failed ")
}
func (d *DataBase) InsertGroupMember(ctx context.Context, groupMember *model_struct.LocalGroupMember) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMember).Error, "")
}
//funcation (d *DataBase) BatchInsertMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error {
// if MessageList == nil {
// return nil
// }
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// return errs.WrapMsg(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertMessageList failed")
//}
func (d *DataBase) BatchInsertGroupMember(ctx context.Context, groupMemberList []*model_struct.LocalGroupMember) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
if groupMemberList == nil {
return errors.New("nil")
}
return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupMemberList).Error, "BatchInsertMessageList failed")
}
func (d *DataBase) DeleteGroupMember(ctx context.Context, groupID, userID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMember model_struct.LocalGroupMember
return d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&groupMember).Error
}
func (d *DataBase) DeleteGroupAllMembers(ctx context.Context, groupID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupMember model_struct.LocalGroupMember
return d.conn.WithContext(ctx).Where("group_id=? ", groupID).Delete(&groupMember).Error
}
func (d *DataBase) UpdateGroupMember(ctx context.Context, groupMember *model_struct.LocalGroupMember) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
t := d.conn.WithContext(ctx).Model(groupMember).Select("*").Updates(*groupMember)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.WrapMsg(t.Error, "")
}
func (d *DataBase) UpdateGroupMemberField(ctx context.Context, groupID, userID string, args map[string]interface{}) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
c := model_struct.LocalGroupMember{GroupID: groupID, UserID: userID}
t := d.conn.WithContext(ctx).Model(&c).Updates(args)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.WrapMsg(t.Error, "UpdateGroupMemberField failed")
}
func (d *DataBase) GetGroupMemberInfoIfOwnerOrAdmin(ctx context.Context) ([]*model_struct.LocalGroupMember, error) {
var ownerAndAdminList []*model_struct.LocalGroupMember
groupList, err := d.GetJoinedGroupListDB(ctx)
if err != nil {
return nil, errs.Wrap(err)
}
for _, v := range groupList {
memberList, err := d.GetGroupOwnerAndAdminByGroupID(ctx, v.GroupID)
if err != nil {
return nil, errs.Wrap(err)
}
ownerAndAdminList = append(ownerAndAdminList, memberList...)
}
return ownerAndAdminList, nil
}
func (d *DataBase) SearchGroupMembersDB(ctx context.Context, keyword string, groupID string, isSearchMemberNickname, isSearchUserID bool, offset, count int) (result []*model_struct.LocalGroupMember, err error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
if !isSearchMemberNickname && !isSearchUserID {
return nil, errors.New("args failed")
}
var countCon int
var condition string
if isSearchUserID {
condition = fmt.Sprintf("user_id like %q ", "%"+keyword+"%")
countCon++
}
if isSearchMemberNickname {
if countCon > 0 {
condition += "or "
}
condition += fmt.Sprintf("nickname like %q ", "%"+keyword+"%")
}
var groupMemberList []model_struct.LocalGroupMember
if groupID != "" {
condition = "( " + condition + " ) "
condition += " and group_id IN ? "
err = d.conn.WithContext(ctx).Where(condition, []string{groupID}).Order("role_level DESC,join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
} else {
err = d.conn.WithContext(ctx).Where(condition).Order("role_level DESC,join_time ASC").Offset(offset).Limit(count).Find(&groupMemberList).Error
}
for _, v := range groupMemberList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) GetGroupMemberAllGroupIDs(ctx context.Context) ([]string, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
// SELECT DISTINCT group_id FROM local_group_members;
var groupIDs []string
err := d.conn.WithContext(ctx).Select("DISTINCT group_id").Model(&model_struct.LocalGroupMember{}).Pluck("group_id", &groupIDs).Error
if err != nil {
return nil, err
}
return groupIDs, nil
}
func (d *DataBase) GetUserJoinedGroupIDs(ctx context.Context, userID string) (groupIDs []string, err error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return groupIDs, d.conn.WithContext(ctx).Model(&model_struct.LocalGroupMember{}).Where("user_id = ?", userID).Pluck("group_id", &groupIDs).Error
}

View File

@@ -0,0 +1,117 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
"gorm.io/gorm"
)
func (d *DataBase) InsertGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupInfo).Error, "InsertGroup failed")
}
func (d *DataBase) DeleteGroup(ctx context.Context, groupID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
localGroup := model_struct.LocalGroup{GroupID: groupID}
return errs.WrapMsg(d.conn.WithContext(ctx).Delete(&localGroup).Error, "DeleteGroup failed")
}
func (d *DataBase) UpdateGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
t := d.conn.WithContext(ctx).Model(groupInfo).Select("*").Updates(*groupInfo)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.Wrap(t.Error)
}
func (d *DataBase) BatchInsertGroup(ctx context.Context, groupList []*model_struct.LocalGroup) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupList).Error, "BatchInsertGroup failed")
}
func (d *DataBase) DeleteAllGroup(ctx context.Context) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&model_struct.LocalGroup{}).Error, "DeleteAllGroup failed")
}
func (d *DataBase) GetJoinedGroupListDB(ctx context.Context) ([]*model_struct.LocalGroup, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupList []*model_struct.LocalGroup
err := d.conn.WithContext(ctx).Find(&groupList).Error
return groupList, errs.WrapMsg(err, "GetJoinedGroupList failed ")
}
func (d *DataBase) GetGroups(ctx context.Context, groupIDs []string) ([]*model_struct.LocalGroup, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupList []*model_struct.LocalGroup
err := d.conn.WithContext(ctx).Where("group_id in (?)", groupIDs).Find(&groupList).Error
return groupList, errs.WrapMsg(err, "GetGroups failed ")
}
func (d *DataBase) GetGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var g model_struct.LocalGroup
return &g, errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id = ?", groupID).Take(&g).Error, "GetGroupList failed")
}
func (d *DataBase) GetAllGroupInfoByGroupIDOrGroupName(ctx context.Context, keyword string, isSearchGroupID bool, isSearchGroupName bool) ([]*model_struct.LocalGroup, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupList []*model_struct.LocalGroup
var condition string
if isSearchGroupID {
if isSearchGroupName {
condition = fmt.Sprintf("group_id like %q or name like %q", "%"+keyword+"%", "%"+keyword+"%")
} else {
condition = fmt.Sprintf("group_id like %q ", "%"+keyword+"%")
}
} else {
condition = fmt.Sprintf("name like %q ", "%"+keyword+"%")
}
err := d.conn.WithContext(ctx).Where(condition).Order("create_time DESC").Find(&groupList).Error
return groupList, errs.WrapMsg(err, "GetAllGroupInfoByGroupIDOrGroupName failed ")
}
func (d *DataBase) AddMemberCount(ctx context.Context, groupID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
group := model_struct.LocalGroup{GroupID: groupID}
return errs.WrapMsg(d.conn.WithContext(ctx).Model(&group).Updates(map[string]interface{}{"member_count": gorm.Expr("member_count+1")}).Error, "")
}
func (d *DataBase) SubtractMemberCount(ctx context.Context, groupID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
group := model_struct.LocalGroup{GroupID: groupID}
return errs.WrapMsg(d.conn.WithContext(ctx).Model(&group).Updates(map[string]interface{}{"member_count": gorm.Expr("member_count-1")}).Error, "")
}

View File

@@ -0,0 +1,53 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) InsertGroupRequest(ctx context.Context, groupRequest *model_struct.LocalGroupRequest) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Create(groupRequest).Error, "InsertGroupRequest failed")
}
func (d *DataBase) DeleteGroupRequest(ctx context.Context, groupID, userID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.WrapMsg(d.conn.WithContext(ctx).Where("group_id=? and user_id=?", groupID, userID).Delete(&model_struct.LocalGroupRequest{}).Error, "DeleteGroupRequest failed")
}
func (d *DataBase) UpdateGroupRequest(ctx context.Context, groupRequest *model_struct.LocalGroupRequest) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
t := d.conn.WithContext(ctx).Model(groupRequest).Select("*").Updates(*groupRequest)
if t.RowsAffected == 0 {
return errs.WrapMsg(errors.New("RowsAffected == 0"), "no update")
}
return errs.Wrap(t.Error)
}
func (d *DataBase) GetSendGroupApplication(ctx context.Context) ([]*model_struct.LocalGroupRequest, error) {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
var groupRequestList []*model_struct.LocalGroupRequest
return groupRequestList, errs.Wrap(d.conn.WithContext(ctx).Order("create_time DESC").Find(&groupRequestList).Error)
}

View File

@@ -0,0 +1,587 @@
// Copyright © 2023 OpenIM SDK. 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_struct
import (
"database/sql/driver"
"encoding/json"
"github.com/openimsdk/tools/errs"
)
//
//message FriendInfo{
//string OwnerUserID = 1;
//string Remark = 2;
//int64 CreateTime = 3;
//UserInfo FriendUser = 4;
//int32 AddSource = 5;
//string OperatorUserID = 6;
//string Ex = 7;
//}
//open_im_sdk.FriendInfo(FriendUser) != imdb.Friend(FriendUserID)
// table = ` CREATE TABLE IF NOT EXISTS friends(
// owner_user_id CHAR (64) NOT NULL,
// friend_user_id CHAR (64) NOT NULL ,
// name varchar(64) DEFAULT NULL ,
// face_url varchar(100) DEFAULT NULL ,
// remark varchar(255) DEFAULT NULL,
// gender int DEFAULT NULL ,
// phone_number varchar(32) DEFAULT NULL ,
// birth INTEGER DEFAULT NULL ,
// email varchar(64) DEFAULT NULL ,
// create_time INTEGER DEFAULT NULL ,
// add_source int DEFAULT NULL ,
// operator_user_id CHAR(64) DEFAULT NULL,
// ex varchar(1024) DEFAULT NULL,
// PRIMARY KEY (owner_user_id,friend_user_id)
// )`
type LocalFriend struct {
OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:varchar(64)" json:"ownerUserID"`
FriendUserID string `gorm:"column:friend_user_id;primary_key;type:varchar(64)" json:"userID"`
Remark string `gorm:"column:remark;type:varchar(255)" json:"remark"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AddSource int32 `gorm:"column:add_source" json:"addSource"`
OperatorUserID string `gorm:"column:operator_user_id;type:varchar(64)" json:"operatorUserID"`
Nickname string `gorm:"column:name;type:varchar;type:varchar(255)" json:"nickname"`
FaceURL string `gorm:"column:face_url;type:varchar;type:varchar(255)" json:"faceURL"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
IsPinned bool `gorm:"column:is_pinned;" json:"isPinned"`
}
func (LocalFriend) TableName() string {
return "local_friends"
}
// message FriendRequest{
// string FromUserID = 1;
// string ToUserID = 2;
// int32 HandleResult = 3;
// string ReqMsg = 4;
// int64 CreateTime = 5;
// string HandlerUserID = 6;
// string HandleMsg = 7;
// int64 HandleTime = 8;
// string Ex = 9;
// }
// open_im_sdk.FriendRequest == imdb.FriendRequest
type LocalFriendRequest struct {
FromUserID string `gorm:"column:from_user_id;primary_key;type:varchar(64)" json:"fromUserID"`
FromNickname string `gorm:"column:from_nickname;type:varchar;type:varchar(255)" json:"fromNickname"`
FromFaceURL string `gorm:"column:from_face_url;type:varchar;type:varchar(255)" json:"fromFaceURL"`
// FromGender int32 `gorm:"column:from_gender" json:"fromGender"`
ToUserID string `gorm:"column:to_user_id;primary_key;type:varchar(64)" json:"toUserID"`
ToNickname string `gorm:"column:to_nickname;type:varchar;type:varchar(255)" json:"toNickname"`
ToFaceURL string `gorm:"column:to_face_url;type:varchar;type:varchar(255)" json:"toFaceURL"`
// ToGender int32 `gorm:"column:to_gender" json:"toGender"`
HandleResult int32 `gorm:"column:handle_result" json:"handleResult"`
ReqMsg string `gorm:"column:req_msg;type:varchar(255)" json:"reqMsg"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
HandlerUserID string `gorm:"column:handler_user_id;type:varchar(64)" json:"handlerUserID"`
HandleMsg string `gorm:"column:handle_msg;type:varchar(255)" json:"handleMsg"`
HandleTime int64 `gorm:"column:handle_time" json:"handleTime"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
}
//message GroupInfo{
// string GroupID = 1;
// string GroupName = 2;
// string NotificationCmd = 3;
// string Introduction = 4;
// string FaceUrl = 5;
// string OwnerUserID = 6;
// uint32 MemberCount = 8;
// int64 CreateTime = 7;
// string Ex = 9;
// int32 Status = 10;
// string CreatorUserID = 11;
// int32 GroupType = 12;
//}
// open_im_sdk.GroupInfo (OwnerUserID , MemberCount )> imdb.Group
// group_id char(64) NOT NULL,
// name varchar(64) DEFAULT NULL ,
// introduction varchar(255) DEFAULT NULL,
// notification varchar(255) DEFAULT NULL,
// face_url varchar(100) DEFAULT NULL,
// group_type int DEFAULT NULL,
// status int DEFAULT NULL,
// creator_user_id char(64) DEFAULT NULL,
// create_time INTEGER DEFAULT NULL,
// ex varchar(1024) DEFAULT NULL,
// PRIMARY KEY (group_id)
// )`
type LocalGroup struct {
GroupID string `gorm:"column:group_id;primary_key;type:varchar(64)" json:"groupID" binding:"required"`
GroupName string `gorm:"column:name;size:255" json:"groupName"`
Notification string `gorm:"column:notification;type:varchar(255)" json:"notification"`
Introduction string `gorm:"column:introduction;type:varchar(255)" json:"introduction"`
FaceURL string `gorm:"column:face_url;type:varchar(255)" json:"faceURL"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
Status int32 `gorm:"column:status" json:"status"`
CreatorUserID string `gorm:"column:creator_user_id;type:varchar(64)" json:"creatorUserID"`
GroupType int32 `gorm:"column:group_type" json:"groupType"`
OwnerUserID string `gorm:"column:owner_user_id;type:varchar(64)" json:"ownerUserID"`
MemberCount int32 `gorm:"column:member_count" json:"memberCount"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
NeedVerification int32 `gorm:"column:need_verification" json:"needVerification"`
LookMemberInfo int32 `gorm:"column:look_member_info" json:"lookMemberInfo"`
ApplyMemberFriend int32 `gorm:"column:apply_member_friend" json:"applyMemberFriend"`
NotificationUpdateTime int64 `gorm:"column:notification_update_time" json:"notificationUpdateTime"`
NotificationUserID string `gorm:"column:notification_user_id;size:64" json:"notificationUserID"`
}
func (LocalGroup) TableName() string {
return "local_groups"
}
//message GroupMemberFullInfo {
//string GroupID = 1 ;
//string UserID = 2 ;
//int32 roleLevel = 3;
//int64 JoinTime = 4;
//string NickName = 5;
//string FaceUrl = 6;
//int32 JoinSource = 8;
//string OperatorUserID = 9;
//string Ex = 10;
//int32 AppMangerLevel = 7; //if >0
//} open_im_sdk.GroupMemberFullInfo(AppMangerLevel) > imdb.GroupMember
// group_id char(64) NOT NULL,
// user_id char(64) NOT NULL,
// nickname varchar(64) DEFAULT NULL,
// user_group_face_url varchar(64) DEFAULT NULL,
// role_level int DEFAULT NULL,
// join_time INTEGER DEFAULT NULL,
// join_source int DEFAULT NULL,
// operator_user_id char(64) NOT NULL,
type LocalGroupMember struct {
GroupID string `gorm:"column:group_id;primary_key;type:varchar(64)" json:"groupID"`
UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"`
Nickname string `gorm:"column:nickname;type:varchar(255)" json:"nickname"`
FaceURL string `gorm:"column:user_group_face_url;type:varchar(255)" json:"faceURL"`
RoleLevel int32 `gorm:"column:role_level;index:index_role_level;" json:"roleLevel"`
JoinTime int64 `gorm:"column:join_time;index:index_join_time;" json:"joinTime"`
JoinSource int32 `gorm:"column:join_source" json:"joinSource"`
InviterUserID string `gorm:"column:inviter_user_id;size:64" json:"inviterUserID"`
MuteEndTime int64 `gorm:"column:mute_end_time;default:0" json:"muteEndTime"`
OperatorUserID string `gorm:"column:operator_user_id;type:varchar(64)" json:"operatorUserID"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
}
func (LocalGroupMember) TableName() string {
return "local_group_members"
}
// message GroupRequest{
// string UserID = 1;
// string GroupID = 2;
// string HandleResult = 3;
// string ReqMsg = 4;
// string HandleMsg = 5;
// int64 ReqTime = 6;
// string HandleUserID = 7;
// int64 HandleTime = 8;
// string Ex = 9;
// }open_im_sdk.GroupRequest == imdb.GroupRequest
type LocalGroupRequest struct {
GroupID string `gorm:"column:group_id;primary_key;type:varchar(64)" json:"groupID"`
GroupName string `gorm:"column:group_name;size:255" json:"groupName"`
Notification string `gorm:"column:notification;type:varchar(255)" json:"notification"`
Introduction string `gorm:"column:introduction;type:varchar(255)" json:"introduction"`
GroupFaceURL string `gorm:"column:face_url;type:varchar(255)" json:"groupFaceURL"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
Status int32 `gorm:"column:status" json:"status"`
CreatorUserID string `gorm:"column:creator_user_id;type:varchar(64)" json:"creatorUserID"`
GroupType int32 `gorm:"column:group_type" json:"groupType"`
OwnerUserID string `gorm:"column:owner_user_id;type:varchar(64)" json:"ownerUserID"`
MemberCount int32 `gorm:"column:member_count" json:"memberCount"`
UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"`
Nickname string `gorm:"column:nickname;type:varchar(255)" json:"nickname"`
UserFaceURL string `gorm:"column:user_face_url;type:varchar(255)" json:"userFaceURL"`
// Gender int32 `gorm:"column:gender" json:"gender"`
HandleResult int32 `gorm:"column:handle_result" json:"handleResult"`
ReqMsg string `gorm:"column:req_msg;type:varchar(255)" json:"reqMsg"`
HandledMsg string `gorm:"column:handle_msg;type:varchar(255)" json:"handledMsg"`
ReqTime int64 `gorm:"column:req_time" json:"reqTime"`
HandleUserID string `gorm:"column:handle_user_id;type:varchar(64)" json:"handleUserID"`
HandledTime int64 `gorm:"column:handle_time" json:"handledTime"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
JoinSource int32 `gorm:"column:join_source" json:"joinSource"`
InviterUserID string `gorm:"column:inviter_user_id;size:64" json:"inviterUserID"`
}
// string UserID = 1;
// string Nickname = 2;
// string FaceUrl = 3;
// int32 Gender = 4;
// string PhoneNumber = 5;
// string Birth = 6;
// string Email = 7;
// string Ex = 8;
// int64 CreateTime = 9;
// int32 AppMangerLevel = 10;
// open_im_sdk.User == imdb.User
type LocalUser struct {
UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"`
Nickname string `gorm:"column:name;type:varchar(255)" json:"nickname"`
FaceURL string `gorm:"column:face_url;type:varchar(255)" json:"faceURL"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AppMangerLevel int32 `gorm:"column:app_manger_level" json:"-"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt" json:"globalRecvMsgOpt"`
}
// message BlackInfo{
// string OwnerUserID = 1;
// int64 CreateTime = 2;
// PublicUserInfo BlackUserInfo = 4;
// int32 AddSource = 5;
// string OperatorUserID = 6;
// string Ex = 7;
// }
// open_im_sdk.BlackInfo(BlackUserInfo) != imdb.Black (BlockUserID)
type LocalBlack struct {
OwnerUserID string `gorm:"column:owner_user_id;primary_key;type:varchar(64)" json:"ownerUserID"`
BlockUserID string `gorm:"column:block_user_id;primary_key;type:varchar(64)" json:"userID"`
Nickname string `gorm:"column:nickname;type:varchar(255)" json:"nickname"`
FaceURL string `gorm:"column:face_url;type:varchar(255)" json:"faceURL"`
// Gender int32 `gorm:"column:gender" json:"gender"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AddSource int32 `gorm:"column:add_source" json:"addSource"`
OperatorUserID string `gorm:"column:operator_user_id;type:varchar(64)" json:"operatorUserID"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
}
type LocalSeqData struct {
UserID string `gorm:"column:user_id;primary_key;type:varchar(64)"`
Seq uint32 `gorm:"column:seq"`
}
type LocalSeq struct {
ID string `gorm:"column:id;primary_key;type:varchar(64)"`
MinSeq uint32 `gorm:"column:min_seq"`
}
// `create table if not exists chat_log (
//
// client_msg_id char(64) NOT NULL,
// server_msg_id char(64) DEFAULT NULL,
// send_id char(64) NOT NULL ,
// is_read int NOT NULL ,
// seq INTEGER DEFAULT NULL ,
// status int NOT NULL ,
// session_type int NOT NULL ,
// recv_id char(64) NOT NULL ,
// content_type int NOT NULL ,
// sender_face_url varchar(100) DEFAULT NULL,
// sender_nick_name varchar(64) DEFAULT NULL,
// msg_from int NOT NULL ,
// content varchar(1000) NOT NULL ,
// sender_platform_id int NOT NULL ,
// send_time INTEGER DEFAULT NULL ,
// create_time INTEGER DEFAULT NULL,
// ex varchar(1024) DEFAULT NULL,
// PRIMARY KEY (client_msg_id)
// )`
// 删除会话,可能会话没有
// 确认删除,告诉会话 ID
// 清空聊天记录的发,会话有,但是聊天记录没有
// DeleteMlessageFromlocalAndSvr
// db
// 不同的会话本地有一个单独的表,其中单聊的话也是这样,有一个单聊的表
// 删除的话,先删除表,在删除本地的 seq ,最后清楚这个表。
// 删除所有的消息的话,全部都是服务器来做,调用接口,然后客户端收到回调,然后删除本地的所有的信息。
// 删除一条信息,删除最新的话,会话上有一条最新的消息,删除这条消息,会话上就没有消息了,此时显示的是第二条。
// 和微信一样,我们 Go get error 分支,然后调用最新的 APi
type LocalChatLog struct {
ClientMsgID string `gorm:"column:client_msg_id;primary_key;type:char(64)" json:"clientMsgID"`
ServerMsgID string `gorm:"column:server_msg_id;type:char(64)" json:"serverMsgID"`
SendID string `gorm:"column:send_id;type:char(64)" json:"sendID"`
RecvID string `gorm:"column:recv_id;index:index_recv_id;type:char(64)" 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" json:"sessionType"`
MsgFrom int32 `gorm:"column:msg_from" json:"msgFrom"`
ContentType int32 `gorm:"column:content_type;index:content_type_alone" json:"contentType"`
Content string `gorm:"column:content;type:varchar(1000)" json:"content"`
IsRead bool `gorm:"column:is_read" json:"isRead"`
Status int32 `gorm:"column:status" json:"status"`
Seq int64 `gorm:"column:seq;index:index_seq;default:0" json:"seq"`
SendTime int64 `gorm:"column:send_time;index:index_send_time;" json:"sendTime"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
LocalEx string `gorm:"column:local_ex;type:varchar(1024)" json:"localEx"`
IsReact bool `gorm:"column:is_react" json:"isReact"`
IsExternalExtensions bool `gorm:"column:is_external_extensions" json:"isExternalExtensions"`
MsgFirstModifyTime int64 `gorm:"column:msg_first_modify_time" json:"msgFirstModifyTime"`
}
type LocalErrChatLog struct {
Seq int64 `gorm:"column:seq;primary_key" json:"seq"`
ClientMsgID string `gorm:"column:client_msg_id;type:char(64)" json:"clientMsgID"`
ServerMsgID string `gorm:"column:server_msg_id;type:char(64)" json:"serverMsgID"`
SendID string `gorm:"column:send_id;type:char(64)" json:"sendID"`
RecvID string `gorm:"column:recv_id;type:char(64)" 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" json:"sessionType"`
MsgFrom int32 `gorm:"column:msg_from" json:"msgFrom"`
ContentType int32 `gorm:"column:content_type" json:"contentType"`
Content string `gorm:"column:content;type:varchar(1000)" json:"content"`
IsRead bool `gorm:"column:is_read" json:"isRead"`
Status int32 `gorm:"column:status" json:"status"`
SendTime int64 `gorm:"column:send_time" json:"sendTime"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
}
type TempCacheLocalChatLog struct {
ClientMsgID string `gorm:"column:client_msg_id;primary_key;type:char(64)" json:"clientMsgID"`
ServerMsgID string `gorm:"column:server_msg_id;type:char(64)" json:"serverMsgID"`
SendID string `gorm:"column:send_id;type:char(64)" json:"sendID"`
RecvID string `gorm:"column:recv_id;type:char(64)" 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" json:"sessionType"`
MsgFrom int32 `gorm:"column:msg_from" json:"msgFrom"`
ContentType int32 `gorm:"column:content_type" json:"contentType"`
Content string `gorm:"column:content;type:varchar(1000)" json:"content"`
IsRead bool `gorm:"column:is_read" json:"isRead"`
Status int32 `gorm:"column:status" json:"status"`
Seq int64 `gorm:"column:seq;default:0" json:"seq"`
SendTime int64 `gorm:"column:send_time;" json:"sendTime"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
}
// `create table if not exists conversation (
//
// conversation_id char(128) NOT NULL,
// conversation_type int(11) NOT NULL,
// user_id varchar(128) DEFAULT NULL,
// group_id varchar(128) DEFAULT NULL,
// show_name varchar(128) NOT NULL,
// face_url varchar(128) NOT NULL,
// recv_msg_opt int(11) NOT NULL ,
// unread_count int(11) NOT NULL ,
// latest_msg varchar(255) NOT NULL ,
// latest_msg_send_time INTEGER(255) NOT NULL ,
// draft_text varchar(255) DEFAULT NULL ,
// draft_timestamp INTEGER(255) DEFAULT NULL ,
// is_pinned int(10) NOT NULL ,
// PRIMARY KEY (conversation_id)
//
// )
type LocalConversation struct {
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"`
ShowName string `gorm:"column:show_name;type:varchar(255)" json:"showName"`
FaceURL string `gorm:"column:face_url;type:varchar(255)" json:"faceURL"`
RecvMsgOpt int32 `gorm:"column:recv_msg_opt" json:"recvMsgOpt"`
UnreadCount int32 `gorm:"column:unread_count" json:"unreadCount"`
GroupAtType int32 `gorm:"column:group_at_type" json:"groupAtType"`
LatestMsg string `gorm:"column:latest_msg;type:varchar(1000)" json:"latestMsg"`
LatestMsgSendTime int64 `gorm:"column:latest_msg_send_time;index:index_latest_msg_send_time" json:"latestMsgSendTime"`
DraftText string `gorm:"column:draft_text" json:"draftText"`
DraftTextTime int64 `gorm:"column:draft_text_time" json:"draftTextTime"`
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"`
IsNotInGroup bool `gorm:"column:is_not_in_group" json:"isNotInGroup"`
UpdateUnreadCountTime int64 `gorm:"column:update_unread_count_time" json:"updateUnreadCountTime"`
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"`
HasReadSeq int64 `gorm:"column:has_read_seq" json:"hasReadSeq"`
MsgDestructTime int64 `gorm:"column:msg_destruct_time;default:604800" json:"msgDestructTime"`
IsMsgDestruct bool `gorm:"column:is_msg_destruct;default:false" json:"isMsgDestruct"`
}
type LocalConversationUnreadMessage struct {
ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"`
ClientMsgID string `gorm:"column:client_msg_id;primary_key;type:char(64)" json:"clientMsgID"`
SendTime int64 `gorm:"column:send_time" json:"sendTime"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
}
// message GroupRequest{
// string UserID = 1;
// string GroupID = 2;
// string HandleResult = 3;
// string ReqMsg = 4;
// string HandleMsg = 5;
// int64 ReqTime = 6;
// string HandleUserID = 7;
// int64 HandleTime = 8;
// string Ex = 9;
// }open_im_sdk.GroupRequest == imdb.GroupRequest
type LocalAdminGroupRequest struct {
LocalGroupRequest
}
type LocalChatLogReactionExtensions struct {
ClientMsgID string `gorm:"column:client_msg_id;primary_key;type:char(64)" json:"clientMsgID"`
LocalReactionExtensions []byte `gorm:"column:local_reaction_extensions" json:"localReactionExtensions"`
}
type LocalWorkMomentsNotification struct {
JsonDetail string `gorm:"column:json_detail"`
CreateTime int64 `gorm:"create_time"`
}
type WorkMomentNotificationMsg struct {
NotificationMsgType int32 `json:"notificationMsgType"`
ReplyUserName string `json:"replyUserName"`
ReplyUserID string `json:"replyUserID"`
Content string `json:"content"`
ContentID string `json:"contentID"`
WorkMomentID string `json:"workMomentID"`
UserID string `json:"userID"`
UserName string `json:"userName"`
FaceURL string `json:"faceURL"`
WorkMomentContent string `json:"workMomentContent"`
CreateTime int32 `json:"createTime"`
}
func (LocalWorkMomentsNotification) TableName() string {
return "local_work_moments_notification"
}
type LocalWorkMomentsNotificationUnreadCount struct {
UnreadCount int `gorm:"unread_count" json:"unreadCount"`
}
func (LocalWorkMomentsNotificationUnreadCount) TableName() string {
return "local_work_moments_notification_unread_count"
}
type NotificationSeqs struct {
ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"`
Seq int64 `gorm:"column:seq" json:"seq"`
}
func (NotificationSeqs) TableName() string {
return "local_notification_seqs"
}
type LocalUpload struct {
PartHash string `gorm:"column:part_hash;primary_key" json:"partHash"`
UploadID string `gorm:"column:upload_id;type:varchar(1000)" json:"uploadID"`
UploadInfo string `gorm:"column:upload_info;type:varchar(2000)" json:"uploadInfo"`
ExpireTime int64 `gorm:"column:expire_time" json:"expireTime"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
}
func (LocalUpload) TableName() string {
return "local_uploads"
}
type LocalStranger struct {
UserID string `gorm:"column:user_id;primary_key;type:varchar(64)" json:"userID"`
Nickname string `gorm:"column:name;type:varchar(255)" json:"nickname"`
FaceURL string `gorm:"column:face_url;type:varchar(255)" json:"faceURL"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
AppMangerLevel int32 `gorm:"column:app_manger_level" json:"-"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
AttachedInfo string `gorm:"column:attached_info;type:varchar(1024)" json:"attachedInfo"`
GlobalRecvMsgOpt int32 `gorm:"column:global_recv_msg_opt" json:"globalRecvMsgOpt"`
}
func (LocalStranger) TableName() string {
return "local_stranger"
}
type LocalSendingMessages struct {
ConversationID string `gorm:"column:conversation_id;primary_key;type:char(128)" json:"conversationID"`
ClientMsgID string `gorm:"column:client_msg_id;primary_key;type:char(64)" json:"clientMsgID"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
}
func (LocalSendingMessages) TableName() string {
return "local_sending_messages"
}
type LocalUserCommand struct {
UserID string `gorm:"column:user_id;type:char(128);primary_key" json:"userID"`
Type int32 `gorm:"column:type;primary_key" json:"type"`
Uuid string `gorm:"column:uuid;type:varchar(255);primary_key" json:"uuid"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
Value string `gorm:"column:value;type:varchar(255)" json:"value"`
Ex string `gorm:"column:ex;type:varchar(1024)" json:"ex"`
}
func (LocalUserCommand) TableName() string {
return "local_user_command"
}
type StringArray []string
func (a StringArray) Value() (driver.Value, error) {
return json.Marshal(a)
}
func (a *StringArray) Scan(value interface{}) error {
b, ok := value.([]byte)
if !ok {
return errs.New("type assertion to []byte failed").Wrap()
}
return json.Unmarshal(b, &a)
}
type LocalVersionSync struct {
Table string `gorm:"column:table;type:varchar(255);primary_key" json:"table"`
EntityID string `gorm:"column:entity_id;type:varchar(255);primary_key" json:"entityID"`
VersionID string `gorm:"column:version_id" json:"versionID"`
Version uint64 `gorm:"column:version" json:"version"`
CreateTime int64 `gorm:"column:create_time" json:"createTime"`
UIDList StringArray `gorm:"column:id_list;type:text" json:"uidList"`
}
func (LocalVersionSync) TableName() string {
return "local_sync_version"
}
type LocalAppSDKVersion struct {
Version string `gorm:"column:version;type:varchar(255);primary_key" json:"version"`
}
func (LocalAppSDKVersion) TableName() string {
return "local_app_sdk_version"
}

View File

@@ -0,0 +1,44 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) SetNotificationSeq(ctx context.Context, conversationID string, seq int64) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
cursor := d.conn.WithContext(ctx).Model(&model_struct.NotificationSeqs{}).Where("conversation_id = ?", conversationID).Updates(map[string]interface{}{"seq": seq})
if cursor.Error != nil {
return utils.Wrap(cursor.Error, "Updates failed")
}
if cursor.RowsAffected == 0 {
return utils.Wrap(d.conn.WithContext(ctx).Create(&model_struct.NotificationSeqs{ConversationID: conversationID, Seq: seq}).Error, "Create failed")
}
return nil
}
func (d *DataBase) GetNotificationAllSeqs(ctx context.Context) ([]*model_struct.NotificationSeqs, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqs []*model_struct.NotificationSeqs
return seqs, utils.Wrap(d.conn.WithContext(ctx).Where("1=1").Find(&seqs).Error, "GetNotificationAllSeqs failed")
}

View File

@@ -0,0 +1,43 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) InsertSendingMessage(ctx context.Context, message *model_struct.LocalSendingMessages) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(message).Error, "InsertSendingMessage failed")
}
func (d *DataBase) DeleteSendingMessage(ctx context.Context, conversationID, clientMsgID string) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
localSendingMessage := model_struct.LocalSendingMessages{ConversationID: conversationID, ClientMsgID: clientMsgID}
return utils.Wrap(d.conn.WithContext(ctx).Delete(&localSendingMessage).Error, "DeleteSendingMessage failed")
}
func (d *DataBase) GetAllSendingMessages(ctx context.Context) (friendRequests []*model_struct.LocalSendingMessages, err error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
err = utils.Wrap(d.conn.WithContext(ctx).Find(&friendRequests).Error, "GetAllSendingMessages failed")
return friendRequests, utils.Wrap(err, "GetAllSendingMessages failed")
}

View File

@@ -0,0 +1,47 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) GetMinSeq(ctx context.Context, ID string) (uint32, error) {
var seqData model_struct.LocalSeq
return seqData.MinSeq, utils.Wrap(d.conn.WithContext(ctx).First(&seqData).Error, "GetMinSeq failed")
}
func (d *DataBase) SetMinSeq(ctx context.Context, ID string, minSeq uint32) error {
seqData := model_struct.LocalSeq{ID: ID, MinSeq: minSeq}
t := d.conn.WithContext(ctx).Updates(&seqData)
if t.RowsAffected == 0 {
return utils.Wrap(d.conn.WithContext(ctx).Create(seqData).Error, "Updates failed")
} else {
return utils.Wrap(t.Error, "SetMinSeq failed")
}
}
func (d *DataBase) GetUserMinSeq(ctx context.Context) (uint32, error) {
return 0, nil
}
func (d *DataBase) GetGroupMinSeq(ctx context.Context, groupID string) (uint32, error) {
return 0, nil
}

View File

@@ -0,0 +1,58 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"gorm.io/gorm"
)
func (d *DataBase) GetStrangerInfo(ctx context.Context, userIDs []string) ([]*model_struct.LocalStranger, error) {
d.friendMtx.Lock()
defer d.friendMtx.Unlock()
var friendList []model_struct.LocalStranger
err := utils.Wrap(d.conn.WithContext(ctx).Where("user_id IN ?", userIDs).Find(&friendList).Error, "GetFriendInfoListByFriendUserID failed")
var transfer []*model_struct.LocalStranger
for _, v := range friendList {
v1 := v
transfer = append(transfer, &v1)
}
return transfer, err
}
func (d *DataBase) SetStrangerInfo(ctx context.Context, localStrangerList []*model_struct.LocalStranger) error {
//TODO Can be optimized into two chan batch update or insert operations
for _, existingData := range localStrangerList {
result := d.conn.First(&existingData, "user_id = ?", existingData.UserID)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
// Data does not exist, perform insert operation
err := d.conn.Create(&existingData).Error
return err
} else if result.Error != nil {
return result.Error
}
err := d.conn.Save(&existingData).Error
if err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,423 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"fmt"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/openimsdk/openim-sdk-core/v3/sdk_struct"
"gorm.io/gorm"
)
func (d *DataBase) initSuperLocalChatLog(ctx context.Context, groupID string) {
if !d.conn.WithContext(ctx).Migrator().HasTable(utils.GetConversationTableName(groupID)) {
d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).AutoMigrate(&model_struct.LocalChatLog{})
}
}
func (d *DataBase) SuperGroupBatchInsertMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog, groupID string) error {
if MessageList == nil {
return nil
}
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(MessageList).Error, "SuperGroupBatchInsertMessageList failed")
}
func (d *DataBase) SuperGroupInsertMessage(ctx context.Context, Message *model_struct.LocalChatLog, groupID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Create(Message).Error, "SuperGroupInsertMessage failed")
}
func (d *DataBase) SuperGroupDeleteAllMessage(ctx context.Context, groupID string) error {
return utils.Wrap(d.conn.WithContext(ctx).Session(&gorm.Session{AllowGlobalUpdate: true}).Table(utils.GetConversationTableName(groupID)).Delete(&model_struct.LocalChatLog{}).Error, "SuperGroupDeleteAllMessage failed")
}
func (d *DataBase) SuperGroupSearchMessageByKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var messageList []model_struct.LocalChatLog
var condition string
var subCondition string
if keywordListMatchType == constant.KeywordMatchOr {
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "or "
}
}
} else {
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "and "
}
}
}
condition = fmt.Sprintf("recv_id=%q And send_time between %d and %d AND status <=%d And content_type IN ? ", sourceID, startTime, endTime, constant.MsgStatusSendFailed)
condition += subCondition
err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "InsertMessage failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) SuperGroupSearchAllMessageByContentType(ctx context.Context, groupID string, contentType int32) (result []*model_struct.LocalChatLog, err error) {
err = d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where("content_type = ?", contentType).Find(&result).Error
return result, err
}
func (d *DataBase) SuperGroupSearchMessageByContentType(ctx context.Context, contentType []int, sourceID string, startTime, endTime int64, sessionType, offset, count int) (result []*model_struct.LocalChatLog, err error) {
var messageList []model_struct.LocalChatLog
var condition string
condition = fmt.Sprintf("session_type=%d And recv_id==%q And send_time between %d and %d AND status <=%d And content_type IN ?", sessionType, sourceID, startTime, endTime, constant.MsgStatusSendFailed)
err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, contentType).Order("send_time DESC").Offset(offset).Limit(count).Find(&messageList).Error, "SearchMessage failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) SuperGroupSearchMessageByContentTypeAndKeyword(ctx context.Context, contentType []int, keywordList []string, keywordListMatchType int, startTime, endTime int64, groupID string) (result []*model_struct.LocalChatLog, err error) {
var messageList []model_struct.LocalChatLog
var condition string
var subCondition string
if keywordListMatchType == constant.KeywordMatchOr {
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "or "
}
}
} else {
for i := 0; i < len(keywordList); i++ {
if i == 0 {
subCondition += "And ("
}
if i+1 >= len(keywordList) {
subCondition += "content like " + "'%" + keywordList[i] + "%') "
} else {
subCondition += "content like " + "'%" + keywordList[i] + "%' " + "and "
}
}
}
condition = fmt.Sprintf("send_time between %d and %d AND status <=%d And content_type IN ? ", startTime, endTime, constant.MsgStatusSendFailed)
condition += subCondition
err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(condition, contentType).Order("send_time DESC").Find(&messageList).Error, "SearchMessage failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) SuperGroupBatchUpdateMessageList(ctx context.Context, MessageList []*model_struct.LocalChatLog) error {
if MessageList == nil {
return nil
}
for _, v := range MessageList {
v1 := new(model_struct.LocalChatLog)
v1.ClientMsgID = v.ClientMsgID
v1.Seq = v.Seq
v1.Status = v.Status
err := d.SuperGroupUpdateMessage(ctx, v1)
if err != nil {
return utils.Wrap(err, "BatchUpdateMessageList failed")
}
}
return nil
}
func (d *DataBase) SuperGroupMessageIfExists(ctx context.Context, ClientMsgID string) (bool, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var count int64
t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("client_msg_id = ?",
ClientMsgID).Count(&count)
if t.Error != nil {
return false, utils.Wrap(t.Error, "MessageIfExists get failed")
}
if count != 1 {
return false, nil
} else {
return true, nil
}
}
func (d *DataBase) SuperGroupIsExistsInErrChatLogBySeq(ctx context.Context, seq int64) bool {
return true
}
func (d *DataBase) SuperGroupMessageIfExistsBySeq(ctx context.Context, seq int64) (bool, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var count int64
t := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("seq = ?",
seq).Count(&count)
if t.Error != nil {
return false, utils.Wrap(t.Error, "MessageIfExistsBySeq get failed")
}
if count != 1 {
return false, nil
} else {
return true, nil
}
}
func (d *DataBase) SuperGroupGetMessage(ctx context.Context, msg *sdk_struct.MsgStruct) (*model_struct.LocalChatLog, error) {
d.initSuperLocalChatLog(ctx, msg.GroupID)
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var c model_struct.LocalChatLog
return &c, utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(msg.GroupID)).Where("client_msg_id = ?",
msg.ClientMsgID).Take(&c).Error, "GetMessage failed")
}
func (d *DataBase) SuperGroupGetAllUnDeleteMessageSeqList(ctx context.Context) ([]uint32, error) {
var seqList []uint32
return seqList, utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Where("status != 4").Select("seq").Find(&seqList).Error, "")
}
func (d *DataBase) SuperGroupUpdateColumnsMessage(ctx context.Context, ClientMsgID, groupID string, args map[string]interface{}) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(
"client_msg_id = ? ", ClientMsgID).Updates(args)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateColumnsConversation failed")
}
func (d *DataBase) SuperGroupUpdateMessage(ctx context.Context, c *model_struct.LocalChatLog) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(c.RecvID)).Updates(c)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateMessage failed")
}
func (d *DataBase) SuperGroupUpdateSpecificContentTypeMessage(ctx context.Context, contentType int, groupID string, args map[string]interface{}) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where("content_type = ?", contentType).Updates(args)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateMessage failed")
}
//funcation (d *DataBase) SuperGroupDeleteAllMessage(ctx context.Context, ) error {
// d.mRWMutex.Lock()
// defer d.mRWMutex.Unlock()
// err := d.conn.WithContext(ctx).Model(&model_struct.LocalChatLog{}).Exec("update local_chat_logs set status = ?,content = ? ", constant.MsgStatusHasDeleted, "").Error
// return utils.Wrap(err, "delete all message error")
//}
func (d *DataBase) SuperGroupUpdateMessageStatusBySourceID(ctx context.Context, sourceID string, status, sessionType int32) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var condition string
if sourceID == d.loginUserID && sessionType == constant.SingleChatType {
condition = "send_id=? And recv_id=? AND session_type=?"
} else {
condition = "(send_id=? or recv_id=?)AND session_type=?"
}
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, sourceID, sessionType).Updates(model_struct.LocalChatLog{Status: status})
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) SuperGroupUpdateMessageTimeAndStatus(ctx context.Context, msg *sdk_struct.MsgStruct) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(msg.GroupID)).Where("client_msg_id=? And seq=?", msg.ClientMsgID, 0).Updates(model_struct.LocalChatLog{Status: msg.Status, SendTime: msg.SendTime, ServerMsgID: msg.ServerMsgID})
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "SuperGroupUpdateMessageTimeAndStatus failed")
}
func (d *DataBase) SuperGroupGetMessageList(ctx context.Context, sourceID string, sessionType, count int, startTime int64, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var messageList []model_struct.LocalChatLog
var condition, timeOrder, timeSymbol string
if isReverse {
timeOrder = "send_time ASC"
timeSymbol = ">"
} else {
timeOrder = "send_time DESC"
timeSymbol = "<"
}
condition = " recv_id = ? AND status <=? And session_type = ? And send_time " + timeSymbol + " ?"
err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType, startTime).
Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) SuperGroupGetMessageListNoTime(ctx context.Context, sourceID string, sessionType, count int, isReverse bool) (result []*model_struct.LocalChatLog, err error) {
d.initSuperLocalChatLog(ctx, sourceID)
var messageList []model_struct.LocalChatLog
var condition, timeOrder string
if isReverse {
timeOrder = "send_time ASC"
} else {
timeOrder = "send_time DESC"
}
condition = "recv_id = ? AND status <=? And session_type = ? "
err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(sourceID)).Where(condition, sourceID, constant.MsgStatusSendFailed, sessionType).
Order(timeOrder).Offset(0).Limit(count).Find(&messageList).Error, "GetMessageList failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) SuperGroupGetSendingMessageList(ctx context.Context, groupID string) (result []*model_struct.LocalChatLog, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var messageList []model_struct.LocalChatLog
err = utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where("status = ?", constant.MsgStatusSending).Find(&messageList).Error, "GetMessageList failed")
for _, v := range messageList {
v1 := v
result = append(result, &v1)
}
return result, err
}
func (d *DataBase) SuperGroupUpdateGroupMessageHasRead(ctx context.Context, msgIDList []string, groupID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(" client_msg_id in ?", msgIDList).Update("is_read", constant.HasRead)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) SuperGroupUpdateGroupMessageFields(ctx context.Context, msgIDList []string, groupID string, args map[string]interface{}) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
t := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(" client_msg_id in ?", msgIDList).Updates(args)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateMessageStatusBySourceID failed")
}
func (d *DataBase) SuperGroupGetNormalMsgSeq(ctx context.Context) (int64, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seq int64
err := d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("IFNULL(max(seq),0)").Find(&seq).Error
return seq, utils.Wrap(err, "GetNormalMsgSeq")
}
func (d *DataBase) SuperGroupGetNormalMinSeq(ctx context.Context, groupID string) (int64, error) {
var seq int64
err := d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Select("IFNULL(min(seq),0)").Where("seq >?", 0).Find(&seq).Error
return seq, utils.Wrap(err, "SuperGroupGetNormalMinSeq")
}
func (d *DataBase) SuperGroupGetTestMessage(ctx context.Context, seq int64) (*model_struct.LocalChatLog, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var c model_struct.LocalChatLog
return &c, utils.Wrap(d.conn.WithContext(ctx).Where("seq = ?",
seq).Find(&c).Error, "GetTestMessage failed")
}
func (d *DataBase) SuperGroupUpdateMsgSenderNickname(ctx context.Context, sendID, nickname string, sType int) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(
"send_id = ? and session_type = ? and sender_nick_name != ? ", sendID, sType, nickname).Updates(
map[string]interface{}{"sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed")
}
func (d *DataBase) SuperGroupUpdateMsgSenderFaceURL(ctx context.Context, sendID, faceURL string, sType int) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Where(
"send_id = ? and session_type = ? and sender_face_url != ? ", sendID, sType, faceURL).Updates(
map[string]interface{}{"sender_face_url": faceURL}).Error, utils.GetSelfFuncName()+" failed")
}
func (d *DataBase) SuperGroupUpdateMsgSenderFaceURLAndSenderNickname(ctx context.Context, sendID, faceURL, nickname string, sessionType int, groupID string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Where(
"send_id = ? and session_type = ?", sendID, sessionType).Updates(
map[string]interface{}{"sender_face_url": faceURL, "sender_nick_name": nickname}).Error, utils.GetSelfFuncName()+" failed")
}
func (d *DataBase) SuperGroupGetMsgSeqByClientMsgID(ctx context.Context, clientMsgID string, groupID string) (uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seq uint32
err := utils.Wrap(d.conn.WithContext(ctx).Table(utils.GetConversationTableName(groupID)).Select("seq").Where("client_msg_id=?", clientMsgID).Take(&seq).Error, utils.GetSelfFuncName()+" failed")
return seq, err
}
func (d *DataBase) SuperGroupGetMsgSeqListByGroupID(ctx context.Context, groupID string) ([]uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqList []uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=?", groupID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed")
return seqList, err
}
func (d *DataBase) SuperGroupGetMsgSeqListByPeerUserID(ctx context.Context, userID string) ([]uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqList []uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? or send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed")
return seqList, err
}
func (d *DataBase) SuperGroupGetMsgSeqListBySelfUserID(ctx context.Context, userID string) ([]uint32, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var seqList []uint32
err := utils.Wrap(d.conn.WithContext(ctx).Model(model_struct.LocalChatLog{}).Select("seq").Where("recv_id=? and send_id=?", userID, userID).Find(&seqList).Error, utils.GetSelfFuncName()+" failed")
return seqList, err
}

View File

@@ -0,0 +1,63 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) InsertSuperGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error {
d.superGroupMtx.Lock()
defer d.superGroupMtx.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Create(groupInfo).Error, "InsertSuperGroup failed")
}
func (d *DataBase) DeleteAllSuperGroup(ctx context.Context) error {
d.superGroupMtx.Lock()
defer d.superGroupMtx.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Delete(&model_struct.LocalGroup{}).Error, "DeleteAllSuperGroup failed")
}
func (d *DataBase) GetSuperGroupInfoByGroupID(ctx context.Context, groupID string) (*model_struct.LocalGroup, error) {
d.superGroupMtx.Lock()
defer d.superGroupMtx.Unlock()
var g model_struct.LocalGroup
return &g, utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Where("group_id = ?", groupID).Take(&g).Error, "GetGroupList failed")
}
func (d *DataBase) UpdateSuperGroup(ctx context.Context, groupInfo *model_struct.LocalGroup) error {
d.superGroupMtx.Lock()
defer d.superGroupMtx.Unlock()
t := d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Select("*").Updates(*groupInfo)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "")
}
func (d *DataBase) DeleteSuperGroup(ctx context.Context, groupID string) error {
d.superGroupMtx.Lock()
defer d.superGroupMtx.Unlock()
localGroup := model_struct.LocalGroup{GroupID: groupID}
return utils.Wrap(d.conn.WithContext(ctx).Table(constant.SuperGroupTableName).Delete(&localGroup).Error, "DeleteSuperGroup failed")
}

View File

@@ -0,0 +1,36 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) BatchInsertTempCacheMessageList(ctx context.Context, MessageList []*model_struct.TempCacheLocalChatLog) error {
if MessageList == nil {
return nil
}
return utils.Wrap(d.conn.WithContext(ctx).Create(MessageList).Error, "BatchInsertTempCacheMessageList failed")
}
func (d *DataBase) InsertTempCacheMessage(ctx context.Context, Message *model_struct.TempCacheLocalChatLog) error {
return utils.Wrap(d.conn.WithContext(ctx).Create(Message).Error, "InsertTempCacheMessage failed")
}

View File

@@ -0,0 +1,75 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"time"
"github.com/openimsdk/tools/errs"
)
func (d *DataBase) GetUpload(ctx context.Context, partHash string) (*model_struct.LocalUpload, error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var upload model_struct.LocalUpload
err := d.conn.WithContext(ctx).Where("part_hash = ?", partHash).Take(&upload).Error
if err != nil {
return nil, errs.Wrap(err)
}
return &upload, nil
}
func (d *DataBase) InsertUpload(ctx context.Context, upload *model_struct.LocalUpload) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return errs.Wrap(d.conn.WithContext(ctx).Create(upload).Error)
}
func (d *DataBase) deleteUpload(ctx context.Context, partHash string) error {
return errs.Wrap(d.conn.WithContext(ctx).Where("part_hash = ?", partHash).Delete(&model_struct.LocalUpload{}).Error)
}
func (d *DataBase) UpdateUpload(ctx context.Context, upload *model_struct.LocalUpload) error {
d.groupMtx.Lock()
defer d.groupMtx.Unlock()
return errs.Wrap(d.conn.WithContext(ctx).Updates(upload).Error)
}
func (d *DataBase) DeleteUpload(ctx context.Context, partHash string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return d.deleteUpload(ctx, partHash)
}
func (d *DataBase) DeleteExpireUpload(ctx context.Context) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
var uploads []*model_struct.LocalUpload
err := d.conn.WithContext(ctx).Where("expire_time <= ?", time.Now().UnixMilli()).Find(&uploads).Error
if err != nil {
return errs.Wrap(err)
}
for _, upload := range uploads {
if err := d.deleteUpload(ctx, upload.PartHash); err != nil {
return err
}
}
return nil
}

View File

@@ -0,0 +1,74 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"github.com/pkg/errors"
)
// ProcessUserCommandAdd adds a new user command to the database.
func (d *DataBase) ProcessUserCommandAdd(ctx context.Context, command *model_struct.LocalUserCommand) error {
d.userMtx.Lock()
defer d.userMtx.Unlock()
userCommand := model_struct.LocalUserCommand{
UserID: command.UserID,
CreateTime: command.CreateTime,
Type: command.Type,
Uuid: command.Uuid,
Value: command.Value,
Ex: command.Ex,
}
return utils.Wrap(d.conn.WithContext(ctx).Create(&userCommand).Error, "ProcessUserCommandAdd failed")
}
// ProcessUserCommandUpdate updates an existing user command in the database.
func (d *DataBase) ProcessUserCommandUpdate(ctx context.Context, command *model_struct.LocalUserCommand) error {
d.userMtx.Lock()
defer d.userMtx.Unlock()
t := d.conn.WithContext(ctx).Model(command).Select("*").Updates(*command)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "")
}
// ProcessUserCommandDelete deletes a user command from the database.
func (d *DataBase) ProcessUserCommandDelete(ctx context.Context, command *model_struct.LocalUserCommand) error {
d.userMtx.Lock()
defer d.userMtx.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Where("type = ? AND uuid = ?", command.Type, command.Uuid).Delete(&model_struct.LocalUserCommand{}).Error,
"ProcessUserCommandDelete failed")
}
// ProcessUserCommandGetAll retrieves user commands from the database.
func (d *DataBase) ProcessUserCommandGetAll(ctx context.Context) ([]*model_struct.LocalUserCommand, error) {
d.userMtx.RLock()
defer d.userMtx.RUnlock()
var commands []*model_struct.LocalUserCommand
err := d.conn.WithContext(ctx).Find(&commands).Error
return commands, utils.Wrap(err, "ProcessUserCommandGetAll failed")
}

View File

@@ -0,0 +1,56 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) GetLoginUser(ctx context.Context, userID string) (*model_struct.LocalUser, error) {
d.userMtx.RLock()
defer d.userMtx.RUnlock()
var user model_struct.LocalUser
return &user, utils.Wrap(d.conn.WithContext(ctx).Where("user_id = ? ", userID).Take(&user).Error, "GetLoginUserInfo failed")
}
func (d *DataBase) UpdateLoginUser(ctx context.Context, user *model_struct.LocalUser) error {
d.userMtx.Lock()
defer d.userMtx.Unlock()
t := d.conn.WithContext(ctx).Model(user).Select("*").Updates(user)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateLoginUser failed")
}
func (d *DataBase) UpdateLoginUserByMap(ctx context.Context, user *model_struct.LocalUser, args map[string]interface{}) error {
d.userMtx.Lock()
defer d.userMtx.Unlock()
t := d.conn.WithContext(ctx).Model(&user).Updates(args)
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "UpdateColumnsConversation failed")
}
func (d *DataBase) InsertLoginUser(ctx context.Context, user *model_struct.LocalUser) error {
d.userMtx.Lock()
defer d.userMtx.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Create(user).Error, "InsertLoginUser failed")
}

View File

@@ -0,0 +1,45 @@
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/tools/errs"
"gorm.io/gorm"
)
func (d *DataBase) GetVersionSync(ctx context.Context, tableName, entityID string) (*model_struct.LocalVersionSync, error) {
d.versionMtx.RLock()
defer d.versionMtx.RUnlock()
var res model_struct.LocalVersionSync
return &res, errs.Wrap(d.conn.WithContext(ctx).Where("`table` = ? and `entity_id` = ?", tableName, entityID).Take(&res).Error)
}
func (d *DataBase) SetVersionSync(ctx context.Context, lv *model_struct.LocalVersionSync) error {
d.versionMtx.Lock()
defer d.versionMtx.Unlock()
var existing model_struct.LocalVersionSync
err := d.conn.WithContext(ctx).Where("`table` = ? AND `entity_id` = ?", lv.Table, lv.EntityID).First(&existing).Error
if err == gorm.ErrRecordNotFound {
if createErr := d.conn.WithContext(ctx).Create(lv).Error; createErr != nil {
return errs.Wrap(createErr)
}
return nil
} else if err != nil {
return errs.Wrap(err)
}
if updateErr := d.conn.WithContext(ctx).Model(&existing).Updates(lv).Error; updateErr != nil {
return errs.Wrap(updateErr)
}
return nil
}
func (d *DataBase) DeleteVersionSync(ctx context.Context, tableName, entityID string) error {
d.versionMtx.Lock()
defer d.versionMtx.Unlock()
localVersionSync := model_struct.LocalVersionSync{Table: tableName, EntityID: entityID}
return errs.WrapMsg(d.conn.WithContext(ctx).Delete(&localVersionSync).Error, "DeleteVersionSync failed")
}

View File

@@ -0,0 +1,96 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"errors"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
"gorm.io/gorm"
"time"
)
func (d *DataBase) InsertWorkMomentsNotification(ctx context.Context, jsonDetail string) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
workMomentsNotification := model_struct.LocalWorkMomentsNotification{
JsonDetail: jsonDetail,
CreateTime: time.Now().Unix(),
}
return utils.Wrap(d.conn.WithContext(ctx).Create(workMomentsNotification).Error, "")
}
func (d *DataBase) GetWorkMomentsNotification(ctx context.Context, offset, count int) (WorkMomentsNotifications []*model_struct.LocalWorkMomentsNotification, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
WorkMomentsNotifications = []*model_struct.LocalWorkMomentsNotification{}
err = utils.Wrap(d.conn.WithContext(ctx).Table("local_work_moments_notification").Order("create_time DESC").Offset(offset).Limit(count).Find(&WorkMomentsNotifications).Error, "")
return WorkMomentsNotifications, err
}
func (d *DataBase) GetWorkMomentsNotificationLimit(ctx context.Context, pageNumber, showNumber int) (WorkMomentsNotifications []*model_struct.LocalWorkMomentsNotification, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
WorkMomentsNotifications = []*model_struct.LocalWorkMomentsNotification{}
err = utils.Wrap(d.conn.WithContext(ctx).Table("local_work_moments_notification").Select("json_detail").Find(WorkMomentsNotifications).Error, "")
return WorkMomentsNotifications, err
}
func (d *DataBase) InitWorkMomentsNotificationUnreadCount(ctx context.Context) error {
var n int64
err := utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Count(&n).Error, "")
if err == nil {
if n == 0 {
c := model_struct.LocalWorkMomentsNotificationUnreadCount{UnreadCount: 0}
return utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Create(c).Error, "IncrConversationUnreadCount failed")
}
}
return err
}
func (d *DataBase) IncrWorkMomentsNotificationUnreadCount(ctx context.Context) error {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
c := model_struct.LocalWorkMomentsNotificationUnreadCount{}
t := d.conn.WithContext(ctx).Model(&c).Where("1=1").Update("unread_count", gorm.Expr("unread_count+?", 1))
if t.RowsAffected == 0 {
return utils.Wrap(errors.New("RowsAffected == 0"), "no update")
}
return utils.Wrap(t.Error, "IncrConversationUnreadCount failed")
}
func (d *DataBase) MarkAllWorkMomentsNotificationAsRead(ctx context.Context) (err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).Where("1=1").Updates(map[string]interface{}{"unread_count": 0}).Error, "")
}
func (d *DataBase) GetWorkMomentsUnReadCount(ctx context.Context) (workMomentsNotificationUnReadCount model_struct.LocalWorkMomentsNotificationUnreadCount, err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
workMomentsNotificationUnReadCount = model_struct.LocalWorkMomentsNotificationUnreadCount{}
err = utils.Wrap(d.conn.WithContext(ctx).Model(&model_struct.LocalWorkMomentsNotificationUnreadCount{}).First(&workMomentsNotificationUnReadCount).Error, "")
return workMomentsNotificationUnReadCount, err
}
func (d *DataBase) ClearWorkMomentsNotification(ctx context.Context) (err error) {
d.mRWMutex.Lock()
defer d.mRWMutex.Unlock()
return utils.Wrap(d.conn.WithContext(ctx).Table("local_work_moments_notification").Where("1=1").Delete(&model_struct.LocalWorkMomentsNotification{}).Error, "")
}

View File

@@ -0,0 +1,50 @@
// Copyright © 2023 OpenIM SDK. 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.
//go:build !js
// +build !js
package db
import (
"context"
"github.com/openimsdk/openim-sdk-core/v3/pkg/constant"
"github.com/openimsdk/openim-sdk-core/v3/pkg/db/model_struct"
"github.com/openimsdk/openim-sdk-core/v3/pkg/utils"
)
func (d *DataBase) GetJoinedWorkingGroupIDList(ctx context.Context) ([]string, error) {
groupList, err := d.GetJoinedGroupListDB(ctx)
if err != nil {
return nil, utils.Wrap(err, "")
}
var groupIDList []string
for _, v := range groupList {
if v.GroupType == constant.WorkingGroup {
groupIDList = append(groupIDList, v.GroupID)
}
}
return groupIDList, nil
}
func (d *DataBase) GetJoinedWorkingGroupList(ctx context.Context) ([]*model_struct.LocalGroup, error) {
groupList, err := d.GetJoinedGroupListDB(ctx)
var transfer []*model_struct.LocalGroup
for _, v := range groupList {
if v.GroupType == constant.WorkingGroup {
transfer = append(transfer, v)
}
}
return transfer, utils.Wrap(err, "GetJoinedSuperGroupList failed ")
}