parent
8d029a7ab3
commit
d9becad8e9
@ -0,0 +1,127 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/db/cache"
|
||||
"Open_IM/pkg/common/db/relation"
|
||||
"Open_IM/pkg/common/db/unrelation"
|
||||
"context"
|
||||
"github.com/dtm-labs/rockscache"
|
||||
_ "github.com/dtm-labs/rockscache"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type GroupInterface interface {
|
||||
FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation.Group, err error)
|
||||
CreateGroup(ctx context.Context, groups []*relation.Group) error
|
||||
DeleteGroupByIDs(ctx context.Context, groupIDs []string) error
|
||||
TakeGroupByID(ctx context.Context, groupID string) (group *relation.Group, err error)
|
||||
|
||||
//mongo
|
||||
GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error)
|
||||
}
|
||||
|
||||
type GroupController struct {
|
||||
database DataBase
|
||||
}
|
||||
|
||||
func NewGroupController(db *gorm.DB, rdb redis.UniversalClient, mgoDB *mongo.Database) GroupInterface {
|
||||
groupController := &GroupController{database: newGroupDatabase(db, rdb, mgoDB)}
|
||||
return groupController
|
||||
}
|
||||
|
||||
func (g *GroupController) FindGroupsByID(ctx context.Context, groupIDs []string) (groups []*relation.Group, err error) {
|
||||
return g.database.Find(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *GroupController) CreateGroup(ctx context.Context, groups []*relation.Group) error {
|
||||
return g.database.Create(ctx, groups)
|
||||
}
|
||||
|
||||
func (g *GroupController) DeleteGroupByIDs(ctx context.Context, groupIDs []string) error {
|
||||
return g.database.Delete(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *GroupController) TakeGroupByID(ctx context.Context, groupID string) (group *relation.Group, err error) {
|
||||
return g.database.Take(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *GroupController) GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) {
|
||||
return g.database.GetSuperGroup(ctx, groupID)
|
||||
}
|
||||
|
||||
type DataBase interface {
|
||||
Find(ctx context.Context, groupIDs []string) (groups []*relation.Group, err error)
|
||||
Create(ctx context.Context, groups []*relation.Group) error
|
||||
Delete(ctx context.Context, groupIDs []string) error
|
||||
Take(ctx context.Context, groupID string) (group *relation.Group, err error)
|
||||
GetSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error)
|
||||
}
|
||||
|
||||
type GroupDataBase struct {
|
||||
sqlDB *relation.Group
|
||||
cache *cache.GroupCache
|
||||
mongoDB *unrelation.SuperGroupMgo
|
||||
}
|
||||
|
||||
func newGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, mgoDB *mongo.Database) DataBase {
|
||||
sqlDB := relation.NewGroupDB(db)
|
||||
database := &GroupDataBase{
|
||||
sqlDB: sqlDB,
|
||||
cache: cache.NewGroupCache(rdb, sqlDB, rockscache.Options{
|
||||
RandomExpireAdjustment: 0.2,
|
||||
DisableCacheRead: false,
|
||||
DisableCacheDelete: false,
|
||||
StrongConsistency: true,
|
||||
}),
|
||||
mongoDB: unrelation.NewSuperGroupMgoDB(mgoDB),
|
||||
}
|
||||
return database
|
||||
}
|
||||
|
||||
func (g *GroupDataBase) Find(ctx context.Context, groupIDs []string) (groups []*relation.Group, err error) {
|
||||
return g.cache.GetGroupsInfoFromCache(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *GroupDataBase) Create(ctx context.Context, groups []*relation.Group) error {
|
||||
return g.sqlDB.Create(ctx, groups)
|
||||
}
|
||||
|
||||
func (g *GroupDataBase) Delete(ctx context.Context, groupIDs []string) error {
|
||||
err := g.sqlDB.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := g.sqlDB.Delete(ctx, groupIDs, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.cache.DelGroupsInfoFromCache(ctx, groupIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (g *GroupDataBase) Take(ctx context.Context, groupID string) (group *relation.Group, err error) {
|
||||
return g.cache.GetGroupInfoFromCache(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *GroupDataBase) Update(ctx context.Context, groups []*relation.Group) error {
|
||||
err := g.sqlDB.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := g.sqlDB.Update(ctx, groups, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
var groupIDs []string
|
||||
for _, group := range groups {
|
||||
groupIDs = append(groupIDs, group.GroupID)
|
||||
}
|
||||
if err := g.cache.DelGroupsInfoFromCache(ctx, groupIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (g *GroupDataBase) GetSuperGroup(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) {
|
||||
return g.mongoDB.GetSuperGroup(ctx, groupID)
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/db/cache"
|
||||
"Open_IM/pkg/common/db/mongoDB"
|
||||
"Open_IM/pkg/common/db/mysql"
|
||||
"context"
|
||||
_ "github.com/dtm-labs/rockscache"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"gorm.io/gorm"
|
||||
//"time"
|
||||
)
|
||||
|
||||
type GroupInterface interface {
|
||||
Find(ctx context.Context, groupIDs []string) (groups []*mysql.Group, err error)
|
||||
Create(ctx context.Context, groups []*mysql.Group) error
|
||||
Delete(ctx context.Context, groupIDs []string) error
|
||||
Take(ctx context.Context, groupID string) (group *mysql.Group, err error)
|
||||
}
|
||||
|
||||
type GroupController struct {
|
||||
db DataBase
|
||||
cache *cache.GroupCache
|
||||
mongo *mongoDB.Client
|
||||
}
|
||||
type DataBase interface {
|
||||
Find(ctx context.Context, groupIDs []string) (groups []*mysql.Group, err error)
|
||||
Create(ctx context.Context, groups []*mysql.Group) error
|
||||
Delete(ctx context.Context, groupIDs []string) error
|
||||
Take(ctx context.Context, groupID string) (group *mysql.Group, err error)
|
||||
DeleteTx(ctx context.Context, groupIDs []string) error
|
||||
}
|
||||
type MySqlDatabase struct {
|
||||
mysql.GroupModelInterface
|
||||
}
|
||||
|
||||
func (m *MySqlDatabase) Delete(ctx context.Context, groupIDs []string) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func NewMySqlDatabase(db mysql.GroupModelInterface) DataBase {
|
||||
return &MySqlDatabase{db}
|
||||
}
|
||||
func (m *MySqlDatabase) DeleteTx(ctx context.Context, groupIDs []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewGroupController(groupModel mysql.GroupModelInterface, rdb redis.UniversalClient, mdb *mongo.Client) *GroupController {
|
||||
return &GroupController{db: NewMySqlDatabase(groupModel)}
|
||||
//groupModel.cache = cache.NewGroupCache(rdb, db, rockscache.Options{
|
||||
// DisableCacheRead: false,
|
||||
// StrongConsistency: true,
|
||||
//})
|
||||
//groupModel.mongo = mongoDB.NewMongoClient(mdb)
|
||||
//return &groupModel
|
||||
}
|
||||
|
||||
func (g *GroupController) Find(ctx context.Context, groupIDs []string) (groups []*mysql.Group, err error) {
|
||||
return g.cache.GetGroupsInfoFromCache(ctx, groupIDs)
|
||||
}
|
||||
|
||||
func (g *GroupController) Create(ctx context.Context, groups []*mysql.Group) error {
|
||||
return g.db.Create(ctx, groups)
|
||||
}
|
||||
|
||||
func (g *GroupController) Delete(ctx context.Context, groupIDs []string) error {
|
||||
err := g.db.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := g.db.Delete(ctx, groupIDs, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.cache.DelGroupsInfoFromCache(ctx, groupIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (g *GroupController) Take(ctx context.Context, groupID string) (group *mysql.Group, err error) {
|
||||
return g.cache.GetGroupInfoFromCache(ctx, groupID)
|
||||
}
|
||||
|
||||
func (g *GroupController) Update(ctx context.Context, groups []*mysql.Group) error {
|
||||
err := g.db.DB.Transaction(func(tx *gorm.DB) error {
|
||||
if err := g.db.Update(ctx, groups, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
var groupIDs []string
|
||||
for _, group := range groups {
|
||||
groupIDs = append(groupIDs, group.GroupID)
|
||||
}
|
||||
if err := g.cache.DelGroupsInfoFromCache(ctx, groupIDs); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
}
|
@ -1 +0,0 @@
|
||||
package mongoDB
|
@ -1,181 +0,0 @@
|
||||
package mongoDB
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/utils"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type SuperGroup struct {
|
||||
GroupID string `bson:"group_id" json:"groupID"`
|
||||
MemberIDList []string `bson:"member_id_list" json:"memberIDList"`
|
||||
}
|
||||
|
||||
type UserToSuperGroup struct {
|
||||
UserID string `bson:"user_id" json:"userID"`
|
||||
GroupIDList []string `bson:"group_id_list" json:"groupIDList"`
|
||||
}
|
||||
|
||||
func New
|
||||
|
||||
func (d *db.DataBases) CreateSuperGroup(groupID string, initMemberIDList []string, memberNumCount int) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
session, err := d.mongoClient.StartSession()
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start session failed")
|
||||
}
|
||||
defer session.EndSession(ctx)
|
||||
sCtx := mongo.NewSessionContext(ctx, session)
|
||||
superGroup := SuperGroup{
|
||||
GroupID: groupID,
|
||||
MemberIDList: initMemberIDList,
|
||||
}
|
||||
_, err = c.InsertOne(sCtx, superGroup)
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
var users []UserToSuperGroup
|
||||
for _, v := range initMemberIDList {
|
||||
users = append(users, UserToSuperGroup{
|
||||
UserID: v,
|
||||
})
|
||||
}
|
||||
upsert := true
|
||||
opts := &options.UpdateOptions{
|
||||
Upsert: &upsert,
|
||||
}
|
||||
c = d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup)
|
||||
//_, err = c.UpdateMany(sCtx, bson.M{"user_id": bson.M{"$in": initMemberIDList}}, bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, opts)
|
||||
//if err != nil {
|
||||
// session.AbortTransaction(ctx)
|
||||
// return utils.Wrap(err, "transaction failed")
|
||||
//}
|
||||
for _, userID := range initMemberIDList {
|
||||
_, err = c.UpdateOne(sCtx, bson.M{"user_id": userID}, bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, opts)
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *db.DataBases) GetSuperGroup(groupID string) (SuperGroup, error) {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
superGroup := SuperGroup{}
|
||||
err := c.FindOne(ctx, bson.M{"group_id": groupID}).Decode(&superGroup)
|
||||
return superGroup, err
|
||||
}
|
||||
|
||||
func (d *db.DataBases) AddUserToSuperGroup(groupID string, userIDList []string) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
session, err := d.mongoClient.StartSession()
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start session failed")
|
||||
}
|
||||
defer session.EndSession(ctx)
|
||||
sCtx := mongo.NewSessionContext(ctx, session)
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start transaction failed")
|
||||
}
|
||||
_, err = c.UpdateOne(sCtx, bson.M{"group_id": groupID}, bson.M{"$addToSet": bson.M{"member_id_list": bson.M{"$each": userIDList}}})
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
c = d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup)
|
||||
var users []UserToSuperGroup
|
||||
for _, v := range userIDList {
|
||||
users = append(users, UserToSuperGroup{
|
||||
UserID: v,
|
||||
})
|
||||
}
|
||||
upsert := true
|
||||
opts := &options.UpdateOptions{
|
||||
Upsert: &upsert,
|
||||
}
|
||||
for _, userID := range userIDList {
|
||||
_, err = c.UpdateOne(sCtx, bson.M{"user_id": userID}, bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, opts)
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
}
|
||||
_ = session.CommitTransaction(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *db.DataBases) RemoverUserFromSuperGroup(groupID string, userIDList []string) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
session, err := d.mongoClient.StartSession()
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start session failed")
|
||||
}
|
||||
defer session.EndSession(ctx)
|
||||
sCtx := mongo.NewSessionContext(ctx, session)
|
||||
_, err = c.UpdateOne(ctx, bson.M{"group_id": groupID}, bson.M{"$pull": bson.M{"member_id_list": bson.M{"$in": userIDList}}})
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
err = d.RemoveGroupFromUser(ctx, sCtx, groupID, userIDList)
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
_ = session.CommitTransaction(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *db.DataBases) GetSuperGroupByUserID(userID string) (UserToSuperGroup, error) {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup)
|
||||
var user UserToSuperGroup
|
||||
_ = c.FindOne(ctx, bson.M{"user_id": userID}).Decode(&user)
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (d *db.DataBases) DeleteSuperGroup(groupID string) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
session, err := d.mongoClient.StartSession()
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start session failed")
|
||||
}
|
||||
defer session.EndSession(ctx)
|
||||
sCtx := mongo.NewSessionContext(ctx, session)
|
||||
superGroup := &SuperGroup{}
|
||||
result := c.FindOneAndDelete(sCtx, bson.M{"group_id": groupID})
|
||||
err = result.Decode(superGroup)
|
||||
if err != nil {
|
||||
session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
if err = d.RemoveGroupFromUser(ctx, sCtx, groupID, superGroup.MemberIDList); err != nil {
|
||||
session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
session.CommitTransaction(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *db.DataBases) RemoveGroupFromUser(ctx, sCtx context.Context, groupID string, userIDList []string) error {
|
||||
var users []UserToSuperGroup
|
||||
for _, v := range userIDList {
|
||||
users = append(users, UserToSuperGroup{
|
||||
UserID: v,
|
||||
})
|
||||
}
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup)
|
||||
_, err := c.UpdateOne(sCtx, bson.M{"user_id": bson.M{"$in": userIDList}}, bson.M{"$pull": bson.M{"group_id_list": groupID}})
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "UpdateOne transaction failed")
|
||||
}
|
||||
return err
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/trace_log"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
//import (
|
||||
// "fmt"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/trace_log"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/trace_log"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
//type GroupMember struct {
|
||||
// GroupID string `gorm:"column:group_id;primaryKey;"`
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
//
|
||||
//func UpdateGroupRequest(groupRequest GroupRequest) error {
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/trace_log"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
//type Register struct {
|
||||
// Account string `gorm:"column:account;primary_key;type:char(255)" json:"account"`
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
@ -1,4 +1,4 @@
|
||||
package mysql
|
||||
package relation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/trace_log"
|
@ -1,4 +1,4 @@
|
||||
package mongoDB
|
||||
package unrelation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
@ -1,4 +1,4 @@
|
||||
package mongoDB
|
||||
package unrelation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
@ -0,0 +1 @@
|
||||
package unrelation
|
@ -0,0 +1,164 @@
|
||||
package unrelation
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/utils"
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"go.mongodb.org/mongo-driver/mongo/readconcern"
|
||||
"go.mongodb.org/mongo-driver/x/mongo/driver/session"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
cSuperGroup = "super_group"
|
||||
cUserToSuperGroup = "user_to_super_group"
|
||||
)
|
||||
|
||||
type SuperGroupMgo struct {
|
||||
mgoDB *mongo.Database
|
||||
superGroupCollection *mongo.Collection
|
||||
userToSuperGroupCollection *mongo.Collection
|
||||
}
|
||||
|
||||
type SuperGroup struct {
|
||||
GroupID string `bson:"group_id" json:"groupID"`
|
||||
MemberIDList []string `bson:"member_id_list" json:"memberIDList"`
|
||||
}
|
||||
|
||||
type UserToSuperGroup struct {
|
||||
UserID string `bson:"user_id" json:"userID"`
|
||||
GroupIDList []string `bson:"group_id_list" json:"groupIDList"`
|
||||
}
|
||||
|
||||
func NewSuperGroupMgoDB(mgoDB *mongo.Database) *SuperGroupMgo {
|
||||
return &SuperGroupMgo{mgoDB: mgoDB, superGroupCollection: mgoDB.Collection(cSuperGroup), userToSuperGroupCollection: mgoDB.Collection(cUserToSuperGroup)}
|
||||
}
|
||||
|
||||
func (db *SuperGroupMgo) CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string, memberNumCount int) error {
|
||||
//ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
//c := db.mgoDB.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
opts := options.Session().SetDefaultReadConcern(readconcern.Majority())
|
||||
return db.mgoDB.Client().UseSessionWithOptions(ctx, opts, func(sCtx mongo.SessionContext) error {
|
||||
err := sCtx.StartTransaction()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
superGroup := SuperGroup{
|
||||
GroupID: groupID,
|
||||
MemberIDList: initMemberIDList,
|
||||
}
|
||||
_, err = db.superGroupCollection.InsertOne(sCtx, superGroup)
|
||||
if err != nil {
|
||||
_ = sCtx.AbortTransaction(ctx)
|
||||
return err
|
||||
}
|
||||
upsert := true
|
||||
opts := &options.UpdateOptions{
|
||||
Upsert: &upsert,
|
||||
}
|
||||
for _, userID := range initMemberIDList {
|
||||
_, err = db.userToSuperGroupCollection.UpdateOne(sCtx, bson.M{"user_id": userID}, bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, opts)
|
||||
if err != nil {
|
||||
_ = sCtx.AbortTransaction(ctx)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return sCtx.CommitTransaction(context.Background())
|
||||
})
|
||||
}
|
||||
|
||||
func (db *SuperGroupMgo) GetSuperGroup(ctx context.Context, groupID string) (*SuperGroup, error) {
|
||||
superGroup := SuperGroup{}
|
||||
err := db.superGroupCollection.FindOne(ctx, bson.M{"group_id": groupID}).Decode(&superGroup)
|
||||
return &superGroup, err
|
||||
}
|
||||
|
||||
func (db *SuperGroupMgo) AddUserToSuperGroup(ctx context.Context, groupID string, userIDList []string) error {
|
||||
opts := options.Session().SetDefaultReadConcern(readconcern.Majority())
|
||||
return db.mgoDB.Client().UseSessionWithOptions(ctx, opts, func(sCtx mongo.SessionContext) error {
|
||||
_, err := db.superGroupCollection.UpdateOne(sCtx, bson.M{"group_id": groupID}, bson.M{"$addToSet": bson.M{"member_id_list": bson.M{"$each": userIDList}}})
|
||||
if err != nil {
|
||||
_ = sCtx.AbortTransaction(ctx)
|
||||
return err
|
||||
}
|
||||
upsert := true
|
||||
opts := &options.UpdateOptions{
|
||||
Upsert: &upsert,
|
||||
}
|
||||
for _, userID := range userIDList {
|
||||
_, err = db.userToSuperGroupCollection.UpdateOne(sCtx, bson.M{"user_id": userID}, bson.M{"$addToSet": bson.M{"group_id_list": groupID}}, opts)
|
||||
if err != nil {
|
||||
_ = sCtx.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
}
|
||||
return sCtx.CommitTransaction(context.Background())
|
||||
})
|
||||
}
|
||||
|
||||
func (d *SuperGroupMgo) RemoverUserFromSuperGroup(groupID string, userIDList []string) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
session, err := d.mongoClient.StartSession()
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start session failed")
|
||||
}
|
||||
defer session.EndSession(ctx)
|
||||
sCtx := mongo.NewSessionContext(ctx, session)
|
||||
_, err = c.UpdateOne(ctx, bson.M{"group_id": groupID}, bson.M{"$pull": bson.M{"member_id_list": bson.M{"$in": userIDList}}})
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
err = d.RemoveGroupFromUser(ctx, sCtx, groupID, userIDList)
|
||||
if err != nil {
|
||||
_ = session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
_ = session.CommitTransaction(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *SuperGroupMgo) GetSuperGroupByUserID(userID string) (UserToSuperGroup, error) {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup)
|
||||
var user UserToSuperGroup
|
||||
_ = c.FindOne(ctx, bson.M{"user_id": userID}).Decode(&user)
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (d *SuperGroupMgo) DeleteSuperGroup(groupID string) error {
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second)
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSuperGroup)
|
||||
session, err := d.mongoClient.StartSession()
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "start session failed")
|
||||
}
|
||||
defer session.EndSession(ctx)
|
||||
sCtx := mongo.NewSessionContext(ctx, session)
|
||||
superGroup := &SuperGroup{}
|
||||
result := c.FindOneAndDelete(sCtx, bson.M{"group_id": groupID})
|
||||
err = result.Decode(superGroup)
|
||||
if err != nil {
|
||||
session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
if err = d.RemoveGroupFromUser(ctx, sCtx, groupID, superGroup.MemberIDList); err != nil {
|
||||
session.AbortTransaction(ctx)
|
||||
return utils.Wrap(err, "transaction failed")
|
||||
}
|
||||
session.CommitTransaction(ctx)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *SuperGroupMgo) RemoveGroupFromUser(ctx, sCtx context.Context, groupID string, userIDList []string) error {
|
||||
c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cUserToSuperGroup)
|
||||
_, err := c.UpdateOne(sCtx, bson.M{"user_id": bson.M{"$in": userIDList}}, bson.M{"$pull": bson.M{"group_id_list": groupID}})
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "UpdateOne transaction failed")
|
||||
}
|
||||
return err
|
||||
}
|
Loading…
Reference in new issue