Blame view

models/schema.go 5.17 KB
765431a4   zhangqijia   增加schema接口, 抽象 mo...
1
  package models
98b0736d   zhangqijia   添加定时器, 检查心跳
2
3
  
  import (
d35f4f81   zhangqijia   fix: 优化proto to i...
4
  	"github.com/golang/protobuf/proto"
4255fd8e   zhangqijia   feat: 更新字段
5
  	"google.golang.org/protobuf/reflect/protoreflect"
765431a4   zhangqijia   增加schema接口, 抽象 mo...
6
  	"pro2d/common/components"
436e0af4   zhangqijia   reactor: dir; Ac...
7
  	"pro2d/common/db/mongoproxy"
765431a4   zhangqijia   增加schema接口, 抽象 mo...
8
  	"pro2d/common/logger"
98b0736d   zhangqijia   添加定时器, 检查心跳
9
10
11
12
  	"reflect"
  	"strings"
  )
  
765431a4   zhangqijia   增加schema接口, 抽象 mo...
13
14
15
16
17
18
19
20
  type SchemaOption func(schema *Schema)
  
  func WithSchemaDB(idb components.IDB) SchemaOption {
  	return func(schema *Schema) {
  		schema.db = idb
  	}
  }
  
0ce6c418   zhangqijia   fix: 修复 bug RoleM...
21
22
  type SchemaMap map[string]components.ISchema
  
98b0736d   zhangqijia   添加定时器, 检查心跳
23
  type Schema struct {
f631f225   zhangqijia   feat: 增加背包系统,以及背包...
24
  	conn         components.IConnection
765431a4   zhangqijia   增加schema接口, 抽象 mo...
25
  	db           components.IDB
33ea26ab   zhangqijia   使用schema封装mongo
26
  	reflectValue *reflect.Value
d771e9e3   zhangqijia   fix: 优化FieldByNam...
27
  	reflectIndex map[string]int
d35f4f81   zhangqijia   fix: 优化proto to i...
28
  	protoIndex   map[string]int
33ea26ab   zhangqijia   使用schema封装mongo
29
  
38dd96b4   zhangqijia   定时器+网络数据 peer 在一条...
30
  	cacheFields map[string]interface{}
33ea26ab   zhangqijia   使用schema封装mongo
31
  
0ce6c418   zhangqijia   fix: 修复 bug RoleM...
32
  	pri    interface{}
98b0736d   zhangqijia   添加定时器, 检查心跳
33
34
35
  	schema interface{}
  }
  
33ea26ab   zhangqijia   使用schema封装mongo
36
37
  func NewSchema(key string, schema interface{}) *Schema {
  	s := reflect.ValueOf(schema)
98b0736d   zhangqijia   添加定时器, 检查心跳
38
  	if s.Kind() == reflect.Ptr {
33ea26ab   zhangqijia   使用schema封装mongo
39
  		s = reflect.ValueOf(schema).Elem()
98b0736d   zhangqijia   添加定时器, 检查心跳
40
  	}
33ea26ab   zhangqijia   使用schema封装mongo
41
42
  	sch := &Schema{
  		reflectValue: &s,
0ce6c418   zhangqijia   fix: 修复 bug RoleM...
43
44
  		cacheFields:  make(map[string]interface{}),
  		schema:       schema,
d771e9e3   zhangqijia   fix: 优化FieldByNam...
45
  		reflectIndex: make(map[string]int),
d35f4f81   zhangqijia   fix: 优化proto to i...
46
  		protoIndex:   make(map[string]int),
d771e9e3   zhangqijia   fix: 优化FieldByNam...
47
48
  	}
  
ddc88bac   zhangqijia   fix: 记录战斗
49
50
51
52
  	p := proto.MessageReflect(schema.(proto.Message)).Descriptor()
  	for i := 0; i < p.Fields().Len(); i++ {
  		sch.protoIndex[strings.ToLower(p.Fields().Get(i).JSONName())] = i
  	}
d35f4f81   zhangqijia   fix: 优化proto to i...
53
  
d771e9e3   zhangqijia   fix: 优化FieldByNam...
54
  	for i := 0; i < s.Type().NumField(); i++ {
eadc9aff   zhangqijia   feat: 增加上阵下阵协议,增加...
55
56
57
58
  		name := s.Type().Field(i).Name
  		if strings.Compare(name[0:1], strings.ToLower(name[0:1])) == 0 {
  			continue
  		}
d35f4f81   zhangqijia   fix: 优化proto to i...
59
  		sch.reflectIndex[strings.ToLower(name)] = i
98b0736d   zhangqijia   添加定时器, 检查心跳
60
  	}
765431a4   zhangqijia   增加schema接口, 抽象 mo...
61
  
436e0af4   zhangqijia   reactor: dir; Ac...
62
  	sch.db = mongoproxy.NewMongoColl(sch.GetSchemaName(), sch)
0ce6c418   zhangqijia   fix: 修复 bug RoleM...
63
  	sch.pri = mongoproxy.GetBsonD(sch.getPriTag(), key)
33ea26ab   zhangqijia   使用schema封装mongo
64
  	return sch
98b0736d   zhangqijia   添加定时器, 检查心跳
65
66
  }
  
101d1cc1   zhangqijia   feat: 一个基于redis的自...
67
68
69
70
71
72
73
74
75
76
77
  func (s *Schema) getPriTag() string {
  	var pri string
  	for i := 0; i < s.reflectValue.Type().NumField(); i++ {
  		if s.reflectValue.Type().Field(i).Tag.Get("pri") == "1" {
  			pri = strings.ToLower(s.reflectValue.Type().Field(i).Name)
  			break
  		}
  	}
  	return pri
  }
  
765431a4   zhangqijia   增加schema接口, 抽象 mo...
78
79
  func (s *Schema) FindIndex() (string, []string) {
  	var index []string
4255fd8e   zhangqijia   feat: 更新字段
80
81
82
  	for i := 0; i < s.reflectValue.Type().NumField(); i++ {
  		if s.reflectValue.Type().Field(i).Tag.Get("index") != "" {
  			js := strings.Split(s.reflectValue.Type().Field(i).Tag.Get("json"), ",")
765431a4   zhangqijia   增加schema接口, 抽象 mo...
83
84
85
86
87
88
  			if len(js) == 0 {
  				continue
  			}
  			index = append(index, js[0])
  		}
  	}
4255fd8e   zhangqijia   feat: 更新字段
89
  	return strings.ToLower(s.reflectValue.Type().Name()), index
98b0736d   zhangqijia   添加定时器, 检查心跳
90
91
  }
  
0ce6c418   zhangqijia   fix: 修复 bug RoleM...
92
  func (s *Schema) Init() {
765431a4   zhangqijia   增加schema接口, 抽象 mo...
93
  	coll, keys := s.FindIndex()
0ce6c418   zhangqijia   fix: 修复 bug RoleM...
94
  	for _, index := range keys {
765431a4   zhangqijia   增加schema接口, 抽象 mo...
95
  		s.db.CreateTable()
98b0736d   zhangqijia   添加定时器, 检查心跳
96
  
765431a4   zhangqijia   增加schema接口, 抽象 mo...
97
98
99
100
101
  		logger.Debug("InitDoc collect: %v, createIndex: %s", coll, index)
  		res, err := s.db.SetUnique(index)
  		if err != nil {
  			logger.Error("InitDoc unique: %s, err: %v", res, err)
  			continue
98b0736d   zhangqijia   添加定时器, 检查心跳
102
103
  		}
  	}
765431a4   zhangqijia   增加schema接口, 抽象 mo...
104
105
106
107
  }
  
  func (s *Schema) GetDB() components.IDB {
  	return s.db
98b0736d   zhangqijia   添加定时器, 检查心跳
108
  }
33ea26ab   zhangqijia   使用schema封装mongo
109
110
111
112
113
114
115
116
117
  
  func (s *Schema) GetPri() interface{} {
  	return s.pri
  }
  
  func (s *Schema) GetSchema() interface{} {
  	return s.schema
  }
  
765431a4   zhangqijia   增加schema接口, 抽象 mo...
118
  func (s *Schema) GetSchemaName() string {
4255fd8e   zhangqijia   feat: 更新字段
119
  	return strings.ToLower(s.reflectValue.Type().Name())
765431a4   zhangqijia   增加schema接口, 抽象 mo...
120
121
  }
  
eadc9aff   zhangqijia   feat: 增加上阵下阵协议,增加...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  func (s *Schema) UpdateSchema(schema interface{}) {
  	sch := reflect.ValueOf(schema)
  	if sch.Kind() == reflect.Ptr {
  		sch = reflect.ValueOf(schema).Elem()
  	}
  	for i := 0; i < sch.Type().NumField(); i++ {
  		name := sch.Type().Field(i).Name
  		if _, ok := s.reflectIndex[strings.ToLower(name)]; !ok {
  			continue
  		}
  		s.SetProperty(sch.Type().Field(i).Name, sch.Field(i).Interface())
  	}
  }
  
f631f225   zhangqijia   feat: 增加背包系统,以及背包...
136
137
138
139
140
141
142
143
  func (s *Schema) SetConn(conn components.IConnection) {
  	s.conn = conn
  }
  
  func (s *Schema) GetConn() components.IConnection {
  	return s.conn
  }
  
33ea26ab   zhangqijia   使用schema封装mongo
144
  func (s *Schema) Load() error {
765431a4   zhangqijia   增加schema接口, 抽象 mo...
145
  	return s.db.Load()
33ea26ab   zhangqijia   使用schema封装mongo
146
147
148
  }
  
  func (s *Schema) Create() error {
765431a4   zhangqijia   增加schema接口, 抽象 mo...
149
  	_, err := s.db.Create()
33ea26ab   zhangqijia   使用schema封装mongo
150
151
152
  	return err
  }
  
eadc9aff   zhangqijia   feat: 增加上阵下阵协议,增加...
153
  //更新缓存字段到数据库
38dd96b4   zhangqijia   定时器+网络数据 peer 在一条...
154
  func (s *Schema) Update() {
eadc9aff   zhangqijia   feat: 增加上阵下阵协议,增加...
155
  	if len(s.cacheFields) > 0 {
a24dea4c   zhangqijia   fix: id自增做了写更新。阵容...
156
157
158
159
  		if err := s.db.UpdateProperties(s.cacheFields); err != nil {
  			logger.Error("%s, UpdateErr: %s", s.GetSchemaName(), err.Error())
  			return
  		}
38dd96b4   zhangqijia   定时器+网络数据 peer 在一条...
160
161
162
163
  		s.cacheFields = make(map[string]interface{})
  	}
  }
  
eadc9aff   zhangqijia   feat: 增加上阵下阵协议,增加...
164
  //更新内存,并把字段缓存
7f269318   zhangqijia   add pb.go; 添加关闭连接...
165
  func (s *Schema) SetProperty(key string, val interface{}) {
d771e9e3   zhangqijia   fix: 优化FieldByNam...
166
167
168
169
170
  	idx, ok := s.reflectIndex[strings.ToLower(key)]
  	if !ok {
  		return
  	}
  	s.reflectValue.Field(idx).Set(reflect.ValueOf(val))
7f269318   zhangqijia   add pb.go; 添加关闭连接...
171
  	s.cacheFields[strings.ToLower(key)] = val
33ea26ab   zhangqijia   使用schema封装mongo
172
173
  }
  
fc3e08ac   zhangqijia   feat: add log com...
174
175
176
177
178
179
180
181
  func (s *Schema) GetProperty(key string) interface{} {
  	idx, ok := s.reflectIndex[strings.ToLower(key)]
  	if !ok {
  		return nil
  	}
  	return s.reflectValue.Field(idx).Interface()
  }
  
eadc9aff   zhangqijia   feat: 增加上阵下阵协议,增加...
182
  //更新内存,并把字段缓存
7f269318   zhangqijia   add pb.go; 添加关闭连接...
183
  func (s *Schema) SetProperties(properties map[string]interface{}) {
33ea26ab   zhangqijia   使用schema封装mongo
184
  	for key, val := range properties {
d771e9e3   zhangqijia   fix: 优化FieldByNam...
185
186
187
188
189
190
  		idx, ok := s.reflectIndex[strings.ToLower(key)]
  		if !ok {
  			continue
  		}
  
  		s.reflectValue.Field(idx).Set(reflect.ValueOf(val))
7f269318   zhangqijia   add pb.go; 添加关闭连接...
191
  		s.cacheFields[strings.ToLower(key)] = val
33ea26ab   zhangqijia   使用schema封装mongo
192
  	}
765431a4   zhangqijia   增加schema接口, 抽象 mo...
193
194
  }
  
c8509ef6   zhangqijia   fix: notify equip...
195
  func (s *Schema) IncrProperty(key string, val int64) int64 {
8aaf28dd   zhangqijia   fix: 修复gm系统修改role...
196
197
  	idx, ok := s.reflectIndex[strings.ToLower(key)]
  	if !ok {
c8509ef6   zhangqijia   fix: notify equip...
198
  		return 0
8aaf28dd   zhangqijia   fix: 修复gm系统修改role...
199
200
201
202
203
204
205
206
207
208
  	}
  	field := s.reflectValue.Field(idx)
  	var v int64
  	switch field.Kind() {
  	case reflect.Int64:
  		v = field.Int() + val
  	case reflect.Int:
  		v = field.Int() + val
  	}
  	s.SetProperty(key, v)
c8509ef6   zhangqijia   fix: notify equip...
209
  	return v
8aaf28dd   zhangqijia   fix: 修复gm系统修改role...
210
211
  }
  
d771e9e3   zhangqijia   fix: 优化FieldByNam...
212
  func (s *Schema) ParseFields(message protoreflect.Message, properties map[string]interface{}) []int32 {
4255fd8e   zhangqijia   feat: 更新字段
213
  	ids := make([]int32, 0, len(properties))
d35f4f81   zhangqijia   fix: 优化proto to i...
214
  
4255fd8e   zhangqijia   feat: 更新字段
215
  	for k, v := range properties {
d35f4f81   zhangqijia   fix: 优化proto to i...
216
217
218
219
220
  		idx, ok := s.protoIndex[strings.ToLower(k)]
  		if !ok {
  			continue
  		}
  		field := message.Descriptor().Fields().Get(idx)
4255fd8e   zhangqijia   feat: 更新字段
221
222
223
224
225
  		if field == nil {
  			continue
  		}
  
  		ids = append(ids, int32(field.Index()))
d35f4f81   zhangqijia   fix: 优化proto to i...
226
  
4255fd8e   zhangqijia   feat: 更新字段
227
228
229
230
231
232
233
  		message.Set(field, protoreflect.ValueOf(v))
  
  		s.SetProperty(k, v)
  	}
  
  	return ids
  }