diff --git a/Makefile b/Makefile index ed281a8..bba8f8d 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ all: ge build run ge: protoc -I./protos --go_out=./protos --go-grpc_out=./protos ./protos/*proto + protoc-go-inject-tag -input=./protos/pb/*.pb.go test: go run test/client.go diff --git a/README.md b/README.md index 3f0125c..3e60aef 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,11 @@ * proto gorm 查询 ## 环境安装 +protoc-go-inject-tag: 目的是往protos文件中打入自定义标签 +```shell +$ go get github.com/favadi/protoc-go-inject-tag +``` + etcd ```shell $ go get go.etcd.io/etcd/client/v3 diff --git a/actions/accountaction.go b/actions/accountaction.go index 64fe323..1c22b56 100644 --- a/actions/accountaction.go +++ b/actions/accountaction.go @@ -10,7 +10,7 @@ import ( ) func (s *AccountServer) RegisterHandler(ctx context.Context, in *pb.Register) (*pb.PubRsp, error) { - ok, account := models.AccountExistByPhone(s.DBName, in.Phone) + ok, account := models.AccountExistByPhone(in.Phone) if !ok { account.Phone = in.Phone account.Password = utils.Md5V(in.Password) diff --git a/actions/basic.go b/actions/basic.go index b765cfb..8ae4bb8 100644 --- a/actions/basic.go +++ b/actions/basic.go @@ -3,7 +3,9 @@ package actions import ( "fmt" "net" + "pro2d/components/db" "pro2d/conf" + "pro2d/utils" ) type BasicServer struct { @@ -17,6 +19,12 @@ 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) + } + listing := fmt.Sprintf(":%d", sConf.Port) lis, err := net.Listen("tcp", listing) if err != nil { diff --git a/actions/server.go b/actions/server.go index b250d5b..f43fe9f 100644 --- a/actions/server.go +++ b/actions/server.go @@ -5,6 +5,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/reflection" "pro2d/conf" + "pro2d/models" "pro2d/protos/pb" "pro2d/utils" ) @@ -35,6 +36,8 @@ func (s *AccountServer)Start() error { return err } + models.InitAccountServerModels() + //new一个grpc gs := grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) @@ -52,7 +55,6 @@ func (s *AccountServer)Stop() { s.BasicServer.Close() } - type GameServer struct{ pb.UnimplementedGameServer *BasicServer @@ -78,6 +80,8 @@ func (s *GameServer)Start() error { return err } + models.InitGameServerModels() + //new一个grpc gs := grpc.NewServer(grpc.UnaryInterceptor(GameServerInterceptor)) diff --git a/cmd/account.go b/cmd/account.go new file mode 100644 index 0000000..bfcf2c4 --- /dev/null +++ b/cmd/account.go @@ -0,0 +1,17 @@ +package main + +import ( + "pro2d/actions" + "pro2d/utils" +) + +func main() { + err := make(chan error) + server := actions.NewAccountServer() + go func() { + defer server.Stop() + err <- server.Start() + }() + + utils.Sugar.Errorf("server error: %v", <- err) +} diff --git a/cmd/game.go b/cmd/game.go new file mode 100644 index 0000000..3366c52 --- /dev/null +++ b/cmd/game.go @@ -0,0 +1,19 @@ +package main + +import ( + "pro2d/actions" + "pro2d/utils" +) + +func main() { + err := make(chan error) + + + server := actions.NewGameServer() + go func() { + defer server.Stop() + err <- server.Start() + }() + + utils.Sugar.Errorf("server error: %v", <- err) +} diff --git a/components/db/mongo.go b/components/db/mongo.go index a9374c3..6b8f6a1 100644 --- a/components/db/mongo.go +++ b/components/db/mongo.go @@ -8,14 +8,18 @@ import ( "go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/readpref" "go.mongodb.org/mongo-driver/x/bsonx" + "sort" "strconv" "time" ) -var MongoDBClient *mongo.Client +var ( + MongoClient *mongo.Client + MongoDatabase *mongo.Database +) //初始化 -func Connect(user, password, host string,port int, MaxNum int, timeOut int) error { +func Connect(user, password, host string,port int, MaxNum int, timeOut int, dbname string) 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) @@ -33,19 +37,42 @@ func Connect(user, password, host string,port int, MaxNum int, timeOut int) erro o.SetMaxPoolSize(uint64(MaxNum)) // 发起链接 var err error - MongoDBClient, err = mongo.Connect(ctx, o) + MongoClient , err = mongo.Connect(ctx, o) if err != nil { return err } // 判断服务是不是可用 - if err = MongoDBClient.Ping(context.Background(), readpref.Primary()); err != nil { + if err = MongoClient.Ping(context.Background(), readpref.Primary()); err != nil { return err } + + MongoDatabase = MongoClient.Database(dbname) return nil } +func CreateCollection(collection string) error { + colls, _ := MongoDatabase.ListCollectionNames(context.TODO(), bson.D{}) + pos := sort.SearchStrings(colls, collection) + if pos != len(colls) { + if collection == colls[pos] { + return MongoDatabase.CreateCollection(context.TODO(), collection) + } + } + return MongoDatabase.CreateCollection(context.TODO(), collection) +} + +func SetUnique(collection string, key string) (string, error) { + return MongoDatabase.Collection(collection).Indexes().CreateOne( + context.TODO(), + mongo.IndexModel{ + Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, + Options: options.Index().SetUnique(true), + }, + ) +} + type MgoColl struct { - mgo *mongo.Collection + collection *mongo.Collection pri interface{} schema interface{} @@ -58,9 +85,9 @@ func GetBsonM(key string, value interface{}) interface{} { return bson.M{key: value} } -func NewMongoColl(database, collection string, pri, schema interface{}) *MgoColl { +func NewMongoColl(collection string, pri, schema interface{}) *MgoColl { return &MgoColl{ - mgo: MongoDBClient.Database(database).Collection(collection), + collection: MongoDatabase.Collection(collection), pri: pri, schema: schema, @@ -75,19 +102,19 @@ func (m *MgoColl)SetDatabase(databases string) { func (m *MgoColl) FindOneKV(key string, value interface{}) *mongo.SingleResult { //collection. filter := bson.D{ {key, value}} - singleResult := m.mgo.FindOne(context.TODO(), filter) + singleResult := m.collection.FindOne(context.TODO(), filter) return singleResult } func (m *MgoColl) FindOne(pri interface{}) *mongo.SingleResult { //collection. - singleResult := m.mgo.FindOne(context.TODO(), pri) + singleResult := m.collection.FindOne(context.TODO(), pri) return singleResult } //插入单个 func (m *MgoColl) InsertOne(value interface{}) *mongo.InsertOneResult { - insertResult, err := m.mgo.InsertOne(context.TODO(), value) + insertResult, err := m.collection.InsertOne(context.TODO(), value) if err != nil { fmt.Println(err) } @@ -96,8 +123,8 @@ func (m *MgoColl) InsertOne(value interface{}) *mongo.InsertOneResult { //查询集合里有多少数据 func (m *MgoColl) CollectionCount() (string, int64) { - size, _ := m.mgo.EstimatedDocumentCount(context.TODO()) - return m.mgo.Name(), size + size, _ := m.collection.EstimatedDocumentCount(context.TODO()) + return m.collection.Name(), size } //按选项查询集合 Skip 跳过 Limit 读取数量 sort 1 ,-1 . 1 为最初时间读取 , -1 为最新时间读取 @@ -108,7 +135,7 @@ func (m *MgoColl) CollectionDocuments(Skip, Limit int64, sort int) *mongo.Cursor {}} findOptions := options.Find().SetSort(SORT).SetLimit(Limit).SetSkip(Skip) //findOptions.SetLimit(i) - temp, _ := m.mgo.Find(context.Background(), filter, findOptions) + temp, _ := m.collection.Find(context.Background(), filter, findOptions) return temp } @@ -126,8 +153,8 @@ func (m *MgoColl) ParsingId(result string) (time.Time, uint64) { func (m *MgoColl) DeleteAndFind(key string, value interface{}) (int64, *mongo.SingleResult) { filter := bson.D{ {key, value}} - singleResult := m.mgo.FindOne(context.TODO(), filter) - DeleteResult, err := m.mgo.DeleteOne(context.TODO(), filter, nil) + singleResult := m.collection.FindOne(context.TODO(), filter) + DeleteResult, err := m.collection.DeleteOne(context.TODO(), filter, nil) if err != nil { fmt.Println("删除时出现错误,你删不掉的~") } @@ -137,7 +164,7 @@ func (m *MgoColl) DeleteAndFind(key string, value interface{}) (int64, *mongo.Si //删除文章 func (m *MgoColl) Delete(key string, value interface{}) int64 { filter := bson.D{ {key, value}} - count, err := m.mgo.DeleteOne(context.TODO(), filter, nil) + count, err := m.collection.DeleteOne(context.TODO(), filter, nil) if err != nil { fmt.Println(err) } @@ -149,7 +176,7 @@ func (m *MgoColl) Delete(key string, value interface{}) int64 { func (m *MgoColl) DeleteMany(key string, value interface{}) int64 { filter := bson.D{ {key, value}} - count, err := m.mgo.DeleteMany(context.TODO(), filter) + count, err := m.collection.DeleteMany(context.TODO(), filter) if err != nil { fmt.Println(err) } @@ -157,8 +184,8 @@ func (m *MgoColl) DeleteMany(key string, value interface{}) int64 { } //索引 -func (m *MgoColl) Index(key string){ - m.mgo.Indexes().CreateOne( +func (m *MgoColl) SetUnique(key string){ + m.collection.Indexes().CreateOne( context.Background(), mongo.IndexModel{ Keys : bsonx.Doc{{key, bsonx.Int32(1)}}, @@ -172,7 +199,7 @@ func (m *MgoColl) FindOneAndUpdate(filter interface{}, update interface{})*mongo //filter := bson.M{"name": "x", "array.name": "b"} //update := bson.M{"array.$[item].detail": "test"} - res := m.mgo.FindOneAndUpdate(context.Background(), + res := m.collection.FindOneAndUpdate(context.Background(), filter, bson.M{"$set": update}) if res.Err() != nil { @@ -182,7 +209,7 @@ func (m *MgoColl) FindOneAndUpdate(filter interface{}, update interface{})*mongo } func (m *MgoColl) UpdateOne(filter interface{}, update interface{})*mongo.UpdateResult { - res, err := m.mgo.UpdateOne(context.TODO(), filter, update) + res, err := m.collection.UpdateOne(context.TODO(), filter, update) if err != nil { return nil } diff --git a/conf/conf.go b/conf/conf.go index 4841a5e..fcf526d 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -5,7 +5,6 @@ import ( lumberjack "gopkg.in/natefinch/lumberjack.v2" "gopkg.in/yaml.v3" "io/ioutil" - "pro2d/components/db" "pro2d/utils" ) @@ -74,9 +73,4 @@ 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("mongodb init error: %v", err) - } } \ No newline at end of file diff --git a/go.mod b/go.mod index d4f3db8..a146d6b 100644 --- a/go.mod +++ b/go.mod @@ -4,9 +4,7 @@ go 1.17 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible - github.com/garyburd/redigo v1.6.3 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/golang/protobuf v1.5.2 go.mongodb.org/mongo-driver v1.8.3 go.uber.org/zap v1.17.0 google.golang.org/grpc v1.38.0 @@ -16,7 +14,10 @@ require ( ) require ( + github.com/favadi/protoc-go-inject-tag v1.3.0 // indirect + github.com/garyburd/redigo v1.6.3 // indirect github.com/go-stack/stack v1.8.0 // indirect + github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index 7cd185b..45705cb 100644 --- a/go.sum +++ b/go.sum @@ -13,6 +13,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/favadi/protoc-go-inject-tag v1.3.0 h1:JPrmsmc/uBShG85uY5xGZIa5WJ0IaNZn6LZhQR9tIQE= +github.com/favadi/protoc-go-inject-tag v1.3.0/go.mod h1:SSkUBgfqw2IJ2p7NPNKWk0Idwxt/qIt2LQgFPUgRGtc= github.com/garyburd/redigo v1.6.3 h1:HCeeRluvAgMusMomi1+6Y5dmFOdYV/JzoRrrbFlkGIc= github.com/garyburd/redigo v1.6.3/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= diff --git a/models/account.go b/models/account.go index 3e8549c..e051fca 100644 --- a/models/account.go +++ b/models/account.go @@ -10,20 +10,20 @@ type AccountModel struct { *pb.AccountInfo } -func AccountExistByPhone(database, phone string) (bool, *AccountModel){ - m := NewAccount(database, phone) +func AccountExistByPhone(phone string) (bool, *AccountModel){ + m := NewAccount(phone) if err := m.Load(); err != nil { return false, m } return true, m } -func NewAccount(database, phone string) *AccountModel { +func NewAccount(phone string) *AccountModel { ac := &pb.AccountInfo{ Phone: phone, } account := &AccountModel{ - MgoColl: db.NewMongoColl(database, "account", db.GetBsonM("phone", phone), ac), + MgoColl: db.NewMongoColl( "account", db.GetBsonM("phone", phone), ac), AccountInfo: ac, } diff --git a/models/hero.go b/models/hero.go index 41fc261..ad01383 100644 --- a/models/hero.go +++ b/models/hero.go @@ -2,7 +2,6 @@ package models import ( "pro2d/components/db" - "pro2d/conf" "pro2d/protos/pb" ) @@ -20,11 +19,13 @@ func GetHeros(hm HeroMap) map[string]*pb.Hero { return h } -func NewHero(h *pb.Hero) *HeroModel { +func NewHero(id int64) *HeroModel { + h := &pb.Hero{ + Id: id, + } m := &HeroModel{ - MgoColl: db.NewMongoColl(conf.GlobalConf.GameConf.DBName, "hero", db.GetBsonM("id", h.Id), h), + MgoColl: db.NewMongoColl("hero", db.GetBsonM("id", h.Id), h), Hero: h, } - m.Load() return m } diff --git a/models/init.go b/models/init.go new file mode 100644 index 0000000..838da05 --- /dev/null +++ b/models/init.go @@ -0,0 +1,40 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/protos/pb" + "pro2d/utils" +) + +func InitDoc(schema ...interface{}) { + for _, s := range schema { + for coll, key := range utils.FindIndex(s) { + if err := db.CreateCollection(coll); err != nil { + utils.Sugar.Errorf("InitDoc err: %v", err) + continue + } + + res, err := db.SetUnique(coll, key) + if err != nil { + utils.Sugar.Errorf("InitDoc unique: %s, err: %v", res, err) + continue + } + } + } +} + +func InitAccountServerModels() { + var schema []interface{} = []interface{}{ + pb.AccountInfo{}, + } + InitDoc(schema...) +} + +func InitGameServerModels() { + var schema []interface{} = []interface{}{ + pb.Hero{}, + pb.Role{}, + pb.Team{}, + } + InitDoc(schema...) +} \ No newline at end of file diff --git a/models/init_test.go b/models/init_test.go new file mode 100644 index 0000000..cd9da65 --- /dev/null +++ b/models/init_test.go @@ -0,0 +1,27 @@ +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) + } + + 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) + } + InitGameServerModels() + db.MongoClient.Disconnect(context.TODO()) +} \ No newline at end of file diff --git a/models/role.go b/models/role.go index 0bc816d..eb154f8 100644 --- a/models/role.go +++ b/models/role.go @@ -3,7 +3,6 @@ package models import ( "fmt" "pro2d/components/db" - "pro2d/conf" "pro2d/protos/pb" ) @@ -17,20 +16,20 @@ type RoleModel struct { } func RoleExistByUid(uid int64) (bool, *RoleModel){ - m := NewRole(&pb.Role{Uid: uid}) + m := NewRole(uid) if err := m.Load(); err != nil { return false, m } return true, m } -func NewRole(r *pb.Role) *RoleModel { +func NewRole(uid int64) *RoleModel { + r := &pb.Role{Uid: uid} m := &RoleModel{ - MgoColl: db.NewMongoColl(conf.GlobalConf.GameConf.DBName, "role", db.GetBsonM("uid", r.Uid), r), + MgoColl: db.NewMongoColl("role", db.GetBsonM("uid", r.Uid), r), Role: r, Heros: make(HeroMap), } - m.Load() return m } @@ -41,7 +40,8 @@ func (m *RoleModel) LoadHero() { } func (m *RoleModel) AddHero(hero *pb.Hero) { - h := NewHero(hero) + h := NewHero(hero.Id) + h.Hero = hero h.Create() m.Heros[fmt.Sprintf("%d%d", m.Role.Id, h.Hero.Id)] = h } \ No newline at end of file diff --git a/models/role_test.go b/models/role_test.go index 14a1e86..fc2044b 100644 --- a/models/role_test.go +++ b/models/role_test.go @@ -24,12 +24,12 @@ func TestNewRole(t *testing.T) { }) role.Save() }else { - role = NewRole(&pb.Role{Uid: uid}) + role = NewRole(uid) role.Role.Id = 1 role.Role.Device = "222222" role.Role.Level = 0 role.Create() - role.Index("uid") + role.SetUnique("uid") } print(role) } \ No newline at end of file diff --git a/models/team.go b/models/team.go new file mode 100644 index 0000000..7141058 --- /dev/null +++ b/models/team.go @@ -0,0 +1,23 @@ +package models + +import ( + "pro2d/components/db" + "pro2d/protos/pb" +) + +type TeamModel struct { + *db.MgoColl + Team *pb.Team +} + +func NewTeam(id int64) *TeamModel{ + data := &pb.Team{ + Id: id, + } + m := &TeamModel{ + MgoColl: db.NewMongoColl( "team", data, data), + Team: data, + } + + return m +} \ No newline at end of file diff --git a/protos b/protos index 5e17b38..e1f5090 160000 --- a/protos +++ b/protos @@ -1 +1 @@ -Subproject commit 5e17b3850ca4465a7d824b8a268f38fc7ac3a9ac +Subproject commit e1f50907a33f6a142cad9db325e80d9027979420 diff --git a/utils/utils.go b/utils/utils.go index 5b55d23..900896d 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1 +1,22 @@ -package utils \ No newline at end of file +package utils + +import ( + "reflect" + "strings" +) + + +func FindIndex(schema interface{}) map[string]string{ + s := reflect.TypeOf(schema) + tb := make(map[string]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] + } + } + return tb +} \ No newline at end of file -- libgit2 0.21.2