package biz import ( "errors" v1 "sandc/api/eonline/v1" go_redis_orm "github.com/fananchong/go-redis-orm.v2" "github.com/gomodule/redigo/redis" "google.golang.org/protobuf/proto" ) type UserData struct { __key string data v1.PbUserData __dirtyData map[string]interface{} __dirtyDataForStructFiled map[string]interface{} __isLoad bool __dbKey string __dbName string __expire uint } func NewUserData(dbName string, key string) *UserData { return &UserData{ __key: key, __dbName: dbName, __dbKey: "UserData:" + key, __dirtyData: make(map[string]interface{}), __dirtyDataForStructFiled: make(map[string]interface{}), } } // 若访问数据库失败返回-1;若 key 存在返回 1 ,否则返回 0 。 func (this *UserData) HasKey() (int, error) { db := go_redis_orm.GetDB(this.__dbName) val, err := redis.Int(db.Do("EXISTS", this.__dbKey)) if err != nil { return -1, err } return val, nil } func (this *UserData) Load() error { if this.__isLoad == true { return errors.New("already load!") } db := go_redis_orm.GetDB(this.__dbName) val, err := redis.Values(db.Do("HGETALL", this.__dbKey)) if err != nil { return err } if len(val) == 0 { return go_redis_orm.ERR_ISNOT_EXIST_KEY } var data struct { Data []byte `redis:"data"` } if err := redis.ScanStruct(val, &data); err != nil { return err } if err := proto.Unmarshal(data.Data, &this.data); err != nil { return err } this.__isLoad = true return nil } func (this *UserData) Save() error { if len(this.__dirtyData) == 0 && len(this.__dirtyDataForStructFiled) == 0 { return nil } for k, _ := range this.__dirtyDataForStructFiled { _ = k if k == "data" { data, err := proto.Marshal(&this.data) if err != nil { return err } this.__dirtyData["data"] = data } } db := go_redis_orm.GetDB(this.__dbName) if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(this.__dirtyData)...); err != nil { return err } if this.__expire != 0 { if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil { return err } } this.__dirtyData = make(map[string]interface{}) this.__dirtyDataForStructFiled = make(map[string]interface{}) return nil } func (this *UserData) Delete() error { db := go_redis_orm.GetDB(this.__dbName) _, err := db.Do("DEL", this.__dbKey) if err == nil { this.__isLoad = false this.__dirtyData = make(map[string]interface{}) this.__dirtyDataForStructFiled = make(map[string]interface{}) } return err } func (this *UserData) IsLoad() bool { return this.__isLoad } func (this *UserData) Expire(v uint) { this.__expire = v } func (this *UserData) GetKey() string { return this.__key } func (this *UserData) DirtyData() (map[string]interface{}, error) { for k, _ := range this.__dirtyDataForStructFiled { _ = k if k == "data" { data, err := proto.Marshal(&this.data) if err != nil { return nil, err } this.__dirtyData["data"] = data } } data := make(map[string]interface{}) for k, v := range this.__dirtyData { data[k] = v } this.__dirtyData = make(map[string]interface{}) this.__dirtyDataForStructFiled = make(map[string]interface{}) return data, nil } func (this *UserData) Save2(dirtyData map[string]interface{}) error { if len(dirtyData) == 0 { return nil } db := go_redis_orm.GetDB(this.__dbName) if _, err := db.Do("HMSET", redis.Args{}.Add(this.__dbKey).AddFlat(dirtyData)...); err != nil { return err } if this.__expire != 0 { if _, err := db.Do("EXPIRE", this.__dbKey, this.__expire); err != nil { return err } } return nil } func (this *UserData) GetData(mutable bool) *v1.PbUserData { if mutable { this.__dirtyDataForStructFiled["data"] = nil } return &this.data }