From 1584eb4bb5401523aaed59ad2fd726baa00ef5e7 Mon Sep 17 00:00:00 2001 From: zqj <582132116@qq.com> Date: Thu, 17 Feb 2022 17:44:24 +0800 Subject: [PATCH] 修复创建唯一索引的bug --- actions/accountaction.go | 24 +++++++++++++++++++++++- actions/basic.go | 6 +----- components/db/mongo.go | 40 ++++++++++++++-------------------------- conf/conf.go | 5 +++++ models/account.go | 2 +- models/equip.go | 24 ++++++++++++++++++++++++ models/hero.go | 3 ++- models/init.go | 11 +++++------ models/init_test.go | 13 +++---------- models/prop.go | 24 ++++++++++++++++++++++++ models/role.go | 22 +++++++++++++--------- models/role_test.go | 32 +++++++++++++++++++++++--------- models/team.go | 3 ++- test/client.go | 20 +++++++++++++++----- utils/utils.go | 35 +++++++++++++++++++++++++++++++---- 15 files changed, 186 insertions(+), 78 deletions(-) create mode 100644 models/equip.go create mode 100644 models/prop.go diff --git a/actions/accountaction.go b/actions/accountaction.go index 1c22b56..06ceae0 100644 --- a/actions/accountaction.go +++ b/actions/accountaction.go @@ -14,7 +14,7 @@ func (s *AccountServer) RegisterHandler(ctx context.Context, in *pb.Register) (* if !ok { account.Phone = in.Phone account.Password = utils.Md5V(in.Password) - account.Uid = conf.SnowFlack.NextVal() + account.Uid = conf.SnowFlack.NextValStr() account.Device = "123123" account.Create() }else { @@ -27,7 +27,29 @@ func (s *AccountServer) RegisterHandler(ctx context.Context, in *pb.Register) (* } func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountInfo) (*pb.CreateTokenRsp, error) { + m := models.NewAccount(in.Phone) + if err := m.Load(); err != nil { + return &pb.CreateTokenRsp{ + Rsp: &pb.PubRsp{ + Code: 1, + Msg: err.Error(), + }, + }, nil + } + + if m.Password != utils.Md5V(in.Password) { + return &pb.CreateTokenRsp{ + Rsp: &pb.PubRsp{ + Code: 2, + Msg: "password error", + }, + }, nil + } + return &pb.CreateTokenRsp{ + Rsp: &pb.PubRsp{ + Code: 0, + }, Token: utils.CreateToken(in), GameService: &pb.ServiceInfo{ Id: "1", diff --git a/actions/basic.go b/actions/basic.go index 8ae4bb8..9d1bbf7 100644 --- a/actions/basic.go +++ b/actions/basic.go @@ -5,7 +5,6 @@ import ( "net" "pro2d/components/db" "pro2d/conf" - "pro2d/utils" ) type BasicServer struct { @@ -20,10 +19,7 @@ func NewServer(db string) *BasicServer { func (b *BasicServer) Start(sConf *conf.SConf) (net.Listener, error) { //初始化数据库 - err := db.Connect(conf.GlobalConf.MongoConf.User, conf.GlobalConf.MongoConf.Password, conf.GlobalConf.MongoConf.Host, conf.GlobalConf.MongoConf.Port, conf.GlobalConf.MongoConf.MaxNum, conf.GlobalConf.MongoConf.TimeOut, sConf.DBName) - if err != nil { - utils.Sugar.Errorf("mongodb init error: %v", err) - } + db.MongoDatabase = db.MongoClient.Database(sConf.DBName) listing := fmt.Sprintf(":%d", sConf.Port) lis, err := net.Listen("tcp", listing) diff --git a/components/db/mongo.go b/components/db/mongo.go index 6b8f6a1..c7a86c6 100644 --- a/components/db/mongo.go +++ b/components/db/mongo.go @@ -8,6 +8,8 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" "go.mongodb.org/mongo-driver/x/bsonx" + "pro2d/utils" + "reflect" "sort" "strconv" "time" @@ -19,7 +21,7 @@ var ( ) //初始化 -func Connect(user, password, host string,port int, MaxNum int, timeOut int, dbname string) error { +func Connect(user, password, host string,port int, MaxNum int, timeOut int) error { var uri string if user!= "" { //uri = fmt.Sprintf("mongodb://%s:%s@%s:%d/%s?w=majority", conf.User, conf.Password, conf.Host, conf.Port, conf.DBName) @@ -46,7 +48,7 @@ func Connect(user, password, host string,port int, MaxNum int, timeOut int, dbna return err } - MongoDatabase = MongoClient.Database(dbname) + //MongoDatabase = MongoClient.Database(dbname) return nil } @@ -85,17 +87,18 @@ func GetBsonM(key string, value interface{}) interface{} { return bson.M{key: value} } -func NewMongoColl(collection string, pri, schema interface{}) *MgoColl { +func NewMongoColl(key string, schema interface{}) *MgoColl { return &MgoColl{ - collection: MongoDatabase.Collection(collection), - - pri: pri, + collection: MongoDatabase.Collection(utils.GetCollName(schema)), + pri: GetBsonM(utils.GetPriKey(schema), key), schema: schema, } } -func (m *MgoColl)SetDatabase(databases string) { - //m.db = databases +func FindOne(pri interface{}, schema interface{}) error { + s := reflect.TypeOf(schema) + r := MongoDatabase.Collection(s.Name()).FindOne(context.TODO(), pri) + return r.Decode(schema) } // 查询单个 @@ -106,21 +109,6 @@ func (m *MgoColl) FindOneKV(key string, value interface{}) *mongo.SingleResult { return singleResult } -func (m *MgoColl) FindOne(pri interface{}) *mongo.SingleResult { - //collection. - singleResult := m.collection.FindOne(context.TODO(), pri) - return singleResult -} - -//插入单个 -func (m *MgoColl) InsertOne(value interface{}) *mongo.InsertOneResult { - insertResult, err := m.collection.InsertOne(context.TODO(), value) - if err != nil { - fmt.Println(err) - } - return insertResult -} - //查询集合里有多少数据 func (m *MgoColl) CollectionCount() (string, int64) { size, _ := m.collection.EstimatedDocumentCount(context.TODO()) @@ -219,7 +207,7 @@ func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.Update func (m *MgoColl) Load() error{ - r := m.FindOne(m.pri) + r := m.collection.FindOne(context.TODO(), m.pri) err := r.Decode(m.schema) if err != nil { return err @@ -227,8 +215,8 @@ func (m *MgoColl) Load() error{ return nil } -func (m *MgoColl) Create() { - m.InsertOne(m.schema) +func (m *MgoColl) Create() (*mongo.InsertOneResult, error){ + return m.collection.InsertOne(context.TODO(), m.schema) } func (m *MgoColl) Update(update interface{}) { diff --git a/conf/conf.go b/conf/conf.go index fcf526d..8834cd1 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -5,6 +5,7 @@ import ( lumberjack "gopkg.in/natefinch/lumberjack.v2" "gopkg.in/yaml.v3" "io/ioutil" + "pro2d/components/db" "pro2d/utils" ) @@ -73,4 +74,8 @@ func init() { //初始化雪花算法 SnowFlack = utils.NewSnowflake(GlobalConf.WorkerID, GlobalConf.DatacenterID) + err = db.Connect(GlobalConf.MongoConf.User, GlobalConf.MongoConf.Password, GlobalConf.MongoConf.Host, GlobalConf.MongoConf.Port, GlobalConf.MongoConf.MaxNum, GlobalConf.MongoConf.TimeOut) + if err != nil { + utils.Sugar.Errorf("connect db err: %v", err) + } } \ No newline at end of file diff --git a/models/account.go b/models/account.go index e051fca..0ac3142 100644 --- a/models/account.go +++ b/models/account.go @@ -23,7 +23,7 @@ func NewAccount(phone string) *AccountModel { Phone: phone, } account := &AccountModel{ - MgoColl: db.NewMongoColl( "account", db.GetBsonM("phone", phone), ac), + MgoColl: db.NewMongoColl(phone, ac), AccountInfo: ac, } diff --git a/models/equip.go b/models/equip.go new file mode 100644 index 0000000..368319d --- /dev/null +++ b/models/equip.go @@ -0,0 +1,24 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/protos/pb" + "strconv" +) + +type EquipModels struct { + *db.MgoColl + Equip *pb.Equipment +} + +func NewEquip(id int64) *EquipModels{ + data := &pb.Equipment{ + Id: id, + } + m := &EquipModels { + MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Equip: data, + } + + return m +} \ No newline at end of file diff --git a/models/hero.go b/models/hero.go index ad01383..4e15e62 100644 --- a/models/hero.go +++ b/models/hero.go @@ -3,6 +3,7 @@ package models import ( "pro2d/components/db" "pro2d/protos/pb" + "strconv" ) type HeroModel struct { @@ -24,7 +25,7 @@ func NewHero(id int64) *HeroModel { Id: id, } m := &HeroModel{ - MgoColl: db.NewMongoColl("hero", db.GetBsonM("id", h.Id), h), + MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), h), Hero: h, } return m diff --git a/models/init.go b/models/init.go index 18918b8..a01abd2 100644 --- a/models/init.go +++ b/models/init.go @@ -8,13 +8,12 @@ import ( func InitDoc(schema ...interface{}) { for _, s := range schema { - for coll, key := range utils.FindIndex(s) { - if err := db.CreateCollection(coll); err != nil { - continue - } + coll, keys := utils.FindIndex(s) + for _, index := range keys { + db.CreateCollection(coll) - utils.Sugar.Debugf("InitDoc collect: %v, createIndex: %s", coll, key) - res, err := db.SetUnique(coll, key) + utils.Sugar.Debugf("InitDoc collect: %v, createIndex: %s", coll, index) + res, err := db.SetUnique(coll, index) if err != nil { utils.Sugar.Errorf("InitDoc unique: %s, err: %v", res, err) continue diff --git a/models/init_test.go b/models/init_test.go index cd9da65..ac108ba 100644 --- a/models/init_test.go +++ b/models/init_test.go @@ -3,25 +3,18 @@ package models import ( "context" "pro2d/components/db" - "pro2d/conf" _ "pro2d/conf" - "pro2d/utils" "testing" ) func TestInitModels(t *testing.T) { - err := db.Connect(conf.GlobalConf.MongoConf.User, conf.GlobalConf.MongoConf.Password, conf.GlobalConf.MongoConf.Host, conf.GlobalConf.MongoConf.Port, conf.GlobalConf.MongoConf.MaxNum, conf.GlobalConf.MongoConf.TimeOut,"account") - if err != nil { - utils.Sugar.Errorf("mongodb init error: %v", err) - } + db.MongoDatabase = db.MongoClient.Database("account") InitAccountServerModels() db.MongoClient.Disconnect(context.TODO()) - err = db.Connect(conf.GlobalConf.MongoConf.User, conf.GlobalConf.MongoConf.Password, conf.GlobalConf.MongoConf.Host, conf.GlobalConf.MongoConf.Port, conf.GlobalConf.MongoConf.MaxNum, conf.GlobalConf.MongoConf.TimeOut,"game") - if err != nil { - utils.Sugar.Errorf("mongodb init error: %v", err) - } + + db.MongoDatabase = db.MongoClient.Database("game") InitGameServerModels() db.MongoClient.Disconnect(context.TODO()) } \ No newline at end of file diff --git a/models/prop.go b/models/prop.go new file mode 100644 index 0000000..a78e679 --- /dev/null +++ b/models/prop.go @@ -0,0 +1,24 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/protos/pb" + "strconv" +) + +type PropModels struct { + *db.MgoColl + Prop *pb.Prop +} + +func NewProp(id int64) *PropModels{ + data := &pb.Prop{ + Id: id, + } + m := &PropModels{ + MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Prop: data, + } + + return m +} \ No newline at end of file diff --git a/models/role.go b/models/role.go index eb154f8..2c87529 100644 --- a/models/role.go +++ b/models/role.go @@ -4,30 +4,34 @@ import ( "fmt" "pro2d/components/db" "pro2d/protos/pb" + "strconv" ) type RoleModel struct { *db.MgoColl Role *pb.Role Heros HeroMap - Teams *pb.Team + Teams *TeamModel Equip *pb.Equipment Prop *pb.Prop } -func RoleExistByUid(uid int64) (bool, *RoleModel){ - m := NewRole(uid) - if err := m.Load(); err != nil { - return false, m +func RoleExistByUid(uid string) (bool, *RoleModel){ + data := &pb.Role{Uid: uid} + + if err := db.FindOne(db.GetBsonM("uid", uid), data); err != nil { + return false, nil } + m := NewRole(data.Id) + m.Load() return true, m } -func NewRole(uid int64) *RoleModel { - r := &pb.Role{Uid: uid} +func NewRole(id int64) *RoleModel { + data := &pb.Role{Id: id} m := &RoleModel{ - MgoColl: db.NewMongoColl("role", db.GetBsonM("uid", r.Uid), r), - Role: r, + MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), + Role: data, Heros: make(HeroMap), } return m diff --git a/models/role_test.go b/models/role_test.go index fc2044b..13efe47 100644 --- a/models/role_test.go +++ b/models/role_test.go @@ -1,18 +1,24 @@ package models import ( + "fmt" + "pro2d/components/db" + "pro2d/conf" "pro2d/protos/pb" + "pro2d/utils" "testing" ) func TestNewRole(t *testing.T) { //db.MongoDBClient.Database(conf.GlobalConf.AccountConf.DBName).Drop(context.Background()) //db.MongoDBClient.Database(conf.GlobalConf.GameConf.DBName).Drop(context.Background()) + db.MongoDatabase = db.MongoClient.Database("game") - var uid int64 = 1 - var role *RoleModel - if ok, role := RoleExistByUid(uid); ok { - role.Role.Device = "111111" + var uid = conf.SnowFlack.NextValStr() + ok, role := RoleExistByUid(uid) + if ok { + //uid存在 , 更新角色 + role.Role.Device = "222222" role.AddHero(&pb.Hero{ Id: 1, RoleId: role.Role.Id, @@ -24,12 +30,20 @@ func TestNewRole(t *testing.T) { }) role.Save() }else { - role = NewRole(uid) - role.Role.Id = 1 - role.Role.Device = "222222" + //uid不存在,创建角色 + role = NewRole(1) + role.Role.Uid = uid + role.Role.Device = "111111" role.Role.Level = 0 - role.Create() - role.SetUnique("uid") + i, err := role.Create() + fmt.Println(i, err) } print(role) +} + +func TestRoleIndex(t *testing.T) { + coll, keys := utils.FindIndex(pb.Role{}) + for _, index := range keys { + utils.Sugar.Debugf("coll: %s, key: %s", coll, index) + } } \ No newline at end of file diff --git a/models/team.go b/models/team.go index 7141058..13b119d 100644 --- a/models/team.go +++ b/models/team.go @@ -3,6 +3,7 @@ package models import ( "pro2d/components/db" "pro2d/protos/pb" + "strconv" ) type TeamModel struct { @@ -15,7 +16,7 @@ func NewTeam(id int64) *TeamModel{ Id: id, } m := &TeamModel{ - MgoColl: db.NewMongoColl( "team", data, data), + MgoColl: db.NewMongoColl(strconv.Itoa(int(id)), data), Team: data, } diff --git a/test/client.go b/test/client.go index 5dff92d..fd8bd76 100644 --- a/test/client.go +++ b/test/client.go @@ -64,16 +64,26 @@ func main() { } defer conn.Close() c := pb.NewAccountClient(conn) - //err = Register(c,"17683852936", "123456") - //if err != nil { - // utils.Sugar.Errorf("register err: %v", err) - // return - //} + err = Register(c,"17683852936", "123456") + if err != nil { + utils.Sugar.Errorf("register err: %v", err) + return + } rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ Phone: "17683852936", Password: "123456", }) + if err != nil { + utils.Sugar.Errorf("createtoken err: %v", err) + return + } + + if rsp.Rsp.Code != 0 { + utils.Sugar.Errorf("createtoken err: %v", rsp.Rsp.Msg) + return + } + Login(rsp.GameService.Address, rsp.Token) diff --git a/utils/utils.go b/utils/utils.go index 900896d..b663ab2 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -5,18 +5,45 @@ import ( "strings" ) +func GetCollName(schema interface{}) string { + s := reflect.TypeOf(schema) + if s.Kind() == reflect.Ptr { + s = reflect.TypeOf(schema).Elem() + } + + return strings.ToLower(s.Name()) +} -func FindIndex(schema interface{}) map[string]string{ +func GetPriKey(schema interface{}) string { s := reflect.TypeOf(schema) - tb := make(map[string]string) + if s.Kind() == reflect.Ptr { + s = reflect.TypeOf(schema).Elem() + } + var pri string + for i := 0; i < s.NumField(); i++ { + if s.Field(i).Tag.Get("pri") == "1" { + pri = strings.ToLower(s.Field(i).Name) + break + } + } + return pri +} + +func FindIndex(schema interface{}) (string, []string){ + s := reflect.TypeOf(schema) + if s.Kind() == reflect.Ptr { + s = reflect.TypeOf(schema).Elem() + } + + var index []string for i := 0; i < s.NumField(); i++ { if s.Field(i).Tag.Get("index") != "" { js := strings.Split(s.Field(i).Tag.Get("json"), ",") if len(js) == 0 { continue } - tb[strings.ToLower(s.Name())] = js[0] + index = append(index, js[0]) } } - return tb + return strings.ToLower(s.Name()), index } \ No newline at end of file -- libgit2 0.21.2