diff --git a/save_test.go b/save_test.go index eca206a..533dfcc 100644 --- a/save_test.go +++ b/save_test.go @@ -10,8 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "git.bit5.ru/backend/dbmeta" "git.bit5.ru/backend/db" + "git.bit5.ru/backend/dbmeta" "git.bit5.ru/backend/meta" "github.com/go-logr/stdr" @@ -19,47 +19,49 @@ import ( var logger = stdr.New(log.New(os.Stdout, "", log.Lshortfile)) -//TODO create the tables below before tests -//CREATE TABLE `player` ( -// `id` int unsigned NOT NULL, -// `client_version` char(16) NOT NULL DEFAULT '', -// `reg_time` int unsigned NOT NULL DEFAULT '0', -// `name` varchar(255) NOT NULL DEFAULT '', -// `utc_delta` tinyint(1) NOT NULL DEFAULT '0', -// PRIMARY KEY (`id`) -//) ENGINE=InnoDB DEFAULT -// -// CREATE TABLE `item` ( -// `player_id` int unsigned NOT NULL DEFAULT '0', -// `id` int unsigned NOT NULL DEFAULT '0', -// `proto_id` int unsigned NOT NULL DEFAULT '0', -// `amount` bigint NOT NULL DEFAULT '0', -// PRIMARY KEY (`player_id`,`id`), -// KEY `proto_id` (`proto_id`) -//) ENGINE=InnoDB DEFAULT - func getDBC() *db.DBC { - s := db.Settings{Host: "127.0.0.1", Port: "3306", User: "root", Pass: "test", Name: "tests_shard_1", Prefix: "tests"} + s := db.Settings{Host: "127.0.0.1", Port: "3306", User: "root", Pass: "test", Name: "tests", Prefix: "tests"} dbc := db.GetDBC(db.OpenPool(s), logger) return dbc } -func cleanStorage(db *db.DBC) { - var tables []string - db.SelectBySQL("SHOW TABLES").LoadValues(&tables) - for _, t := range tables { - _, err := db.DeleteFrom(t).Exec() - if err != nil { - panic(err) - } +func setupStorage(db *db.DBC) { + + var sqls []string + sqls = append(sqls, "DROP TABLE IF EXISTS player") + sqls = append(sqls, `CREATE TABLE player ( + id int unsigned NOT NULL, + client_version char(16) NOT NULL DEFAULT '', + reg_time int unsigned NOT NULL DEFAULT '0', + name varchar(255) NOT NULL DEFAULT '', + utc_delta tinyint(1) NOT NULL DEFAULT '0', + PRIMARY KEY (id) +) ENGINE=InnoDB +`) + sqls = append(sqls, "DROP TABLE IF EXISTS item") + sqls = append(sqls, `CREATE TABLE item ( + player_id int unsigned NOT NULL DEFAULT '0', + id int unsigned NOT NULL DEFAULT '0', + proto_id int unsigned NOT NULL DEFAULT '0', + amount bigint NOT NULL DEFAULT '0', + PRIMARY KEY (player_id,id), + KEY proto_id (proto_id) +) ENGINE=InnoDB +`) + + for _, sql := range sqls { + _, err := db.DB().Exec(sql) + if err != nil { + panic(sql) } + } } func TestSaveRow(t *testing.T) { ctx := context.TODO() conn := getDBC() - cleanStorage(conn) + setupStorage(conn) //DataPlayer index //id 0 @@ -84,7 +86,7 @@ func TestSaveItemCollectionWithMask(t *testing.T) { ctx := context.TODO() conn := getDBC() - cleanStorage(conn) + setupStorage(conn) ownerId := uint32(1) @@ -128,7 +130,7 @@ func TestSaveItemCollectionWithoutMask(t *testing.T) { ctx := context.TODO() conn := getDBC() - cleanStorage(conn) + setupStorage(conn) ownerId := uint32(1) @@ -177,394 +179,425 @@ func TestRemoveIds(t *testing.T) { /////////////////////////////////////////////////////////////////////////////// type DataPlayer struct { - - Id uint32 `json:"id" db:"id"` - Client_version string `json:"client_version" db:"client_version"` - Reg_time uint32 `json:"reg_time" db:"reg_time"` - Name string `json:"name" db:"name"` - Utc_delta int32 `json:"utc_delta" db:"utc_delta"` -fieldsMask meta.FieldsMask - + Id uint32 `json:"id" db:"id"` + Client_version string `json:"client_version" db:"client_version"` + Reg_time uint32 `json:"reg_time" db:"reg_time"` + Name string `json:"name" db:"name"` + Utc_delta int32 `json:"utc_delta" db:"utc_delta"` + fieldsMask meta.FieldsMask } -var _DataPlayer_class_props map[string]string = map[string]string{"POD": "","bitfields": "","pkey": "id","table": "player","owner": "id","id": "id","cloneable": "",} -var _DataPlayer_class_fields []string = []string{"id","client_version","reg_time","name","utc_delta"} -var _DataPlayer_fields_props meta.ClassFieldsProps = map[string]map[string]string{"Id" : map[string]string{"optional": "1",},"Client_version" : map[string]string{"strmax": "16","optional": "1",},"Reg_time" : map[string]string{"default": "","optional": "1",},"Name" : map[string]string{"default": "\"\"","optional": "1",},"Utc_delta" : map[string]string{"default": "","optional": "1",}} +var _DataPlayer_class_props map[string]string = map[string]string{"POD": "", "bitfields": "", "pkey": "id", "table": "player", "owner": "id", "id": "id", "cloneable": ""} +var _DataPlayer_class_fields []string = []string{"id", "client_version", "reg_time", "name", "utc_delta"} +var _DataPlayer_fields_props meta.ClassFieldsProps = map[string]map[string]string{"Id": map[string]string{"optional": "1"}, "Client_version": map[string]string{"strmax": "16", "optional": "1"}, "Reg_time": map[string]string{"default": "", "optional": "1"}, "Name": map[string]string{"default": "\"\"", "optional": "1"}, "Utc_delta": map[string]string{"default": "", "optional": "1"}} func DataPlayer_CLASS_ID() uint32 { - return 74407040 + return 74407040 } type IDataPlayer interface { - meta.IMetaStruct - PtrDataPlayer() *DataPlayer + meta.IMetaStruct + PtrDataPlayer() *DataPlayer } func (*DataPlayer) CLASS_ID() uint32 { - return 74407040 + return 74407040 } func (*DataPlayer) CLASS_NAME() string { - return "DataPlayer" + return "DataPlayer" } func (*DataPlayer) CLASS_PROPS() *map[string]string { - return &_DataPlayer_class_props + return &_DataPlayer_class_props } func (*DataPlayer) CLASS_FIELDS() []string { - return _DataPlayer_class_fields + return _DataPlayer_class_fields } func (*DataPlayer) CLASS_FIELDS_PROPS() *meta.ClassFieldsProps { - return &_DataPlayer_fields_props + return &_DataPlayer_fields_props } //convenience getter func PtrDataPlayer(m meta.IMetaStruct) *DataPlayer { - p, ok := m.(IDataPlayer) - if !ok { - return nil - } - return p.PtrDataPlayer() + p, ok := m.(IDataPlayer) + if !ok { + return nil + } + return p.PtrDataPlayer() } func (self *DataPlayer) PtrDataPlayer() *DataPlayer { - return self + return self } func NewDataPlayer() *DataPlayer { - item := new (DataPlayer) - item.Reset() - return item + item := new(DataPlayer) + item.Reset() + return item } func (self *DataPlayer) Reset() { - - self.Id = 0 - self.Client_version = "" - self.Reg_time = 0 - self.Name = "" - self.Utc_delta = 0 -self.fieldsMask = meta.FieldsMask{} + + self.Id = 0 + self.Client_version = "" + self.Reg_time = 0 + self.Name = "" + self.Utc_delta = 0 + self.fieldsMask = meta.FieldsMask{} } func (self *DataPlayer) Read(reader meta.Reader) error { - return meta.ReadStruct(reader, self, "") + return meta.ReadStruct(reader, self, "") } func (self *DataPlayer) ReadFields(reader meta.Reader) error { - self.Reset() - - use_mask, mask, err := reader.TryReadMask() + self.Reset() - if err != nil { + use_mask, mask, err := reader.TryReadMask() - return err + if err != nil { - } + return err - self.fieldsMask = mask + } - _cont_size, err := reader.GetContainerSize() - if err != nil { - return err - } - if _cont_size < 0 { - _cont_size = 0 - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(0)) { - if err := reader.ReadU32(&self.Id, "id"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(1)) { - if err := reader.ReadString(&self.Client_version, "client_version"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(2)) { - if err := reader.ReadU32(&self.Reg_time, "reg_time"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(3)) { - if err := reader.ReadString(&self.Name, "name"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(4)) { - if err := reader.ReadI32(&self.Utc_delta, "utc_delta"); err != nil { return /*optional*/nil } - } - return nil + self.fieldsMask = mask + + _cont_size, err := reader.GetContainerSize() + if err != nil { + return err + } + if _cont_size < 0 { + _cont_size = 0 + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(0)) { + if err := reader.ReadU32(&self.Id, "id"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(1)) { + if err := reader.ReadString(&self.Client_version, "client_version"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(2)) { + if err := reader.ReadU32(&self.Reg_time, "reg_time"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(3)) { + if err := reader.ReadString(&self.Name, "name"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(4)) { + if err := reader.ReadI32(&self.Utc_delta, "utc_delta"); err != nil { + return /*optional*/ nil + } + } + return nil } func (self *DataPlayer) Write(writer meta.Writer) error { - return meta.WriteStruct(writer, self, "") + return meta.WriteStruct(writer, self, "") } func (self *DataPlayer) WriteFields(writer meta.Writer) error { - - if err := writer.WriteU32(self.Id, "id"); err != nil { return err } - if err := writer.WriteString(self.Client_version, "client_version"); err != nil { return err } + if err := writer.WriteU32(self.Id, "id"); err != nil { + return err + } - if err := writer.WriteU32(self.Reg_time, "reg_time"); err != nil { return err } + if err := writer.WriteString(self.Client_version, "client_version"); err != nil { + return err + } - if err := writer.WriteString(self.Name, "name"); err != nil { return err } + if err := writer.WriteU32(self.Reg_time, "reg_time"); err != nil { + return err + } - if err := writer.WriteI32(self.Utc_delta, "utc_delta"); err != nil { return err } + if err := writer.WriteString(self.Name, "name"); err != nil { + return err + } - return nil + if err := writer.WriteI32(self.Utc_delta, "utc_delta"); err != nil { + return err + } + + return nil } -func(self *DataPlayer) HasValue(index uint64) bool { - return self.fieldsMask.FieldChanged(index) +func (self *DataPlayer) HasValue(index uint64) bool { + return self.fieldsMask.FieldChanged(index) } -func(self *DataPlayer) SetFieldChanged(index uint64) { - self.fieldsMask.SetFieldChanged(index) +func (self *DataPlayer) SetFieldChanged(index uint64) { + self.fieldsMask.SetFieldChanged(index) } -func(self *DataPlayer) IsMaskFilled() bool { - return self.fieldsMask.IsFilled() +func (self *DataPlayer) IsMaskFilled() bool { + return self.fieldsMask.IsFilled() } -func(self *DataPlayer) GetMask() meta.FieldsMask { - return self.fieldsMask +func (self *DataPlayer) GetMask() meta.FieldsMask { + return self.fieldsMask } type DataItem struct { - - Id uint32 `json:"id" db:"id"` - Player_id uint32 `json:"player_id" db:"player_id"` - Proto_id uint32 `json:"proto_id" db:"proto_id"` - Amount int64 `json:"amount" db:"amount"` -fieldsMask meta.FieldsMask - + Id uint32 `json:"id" db:"id"` + Player_id uint32 `json:"player_id" db:"player_id"` + Proto_id uint32 `json:"proto_id" db:"proto_id"` + Amount int64 `json:"amount" db:"amount"` + fieldsMask meta.FieldsMask } -var _DataItem_class_props map[string]string = map[string]string{"POD": "","table": "item","id": "id","owner": "player_id","bitfields": "",} -var _DataItem_class_fields []string = []string{"id","player_id","proto_id","amount",} -var _DataItem_fields_props meta.ClassFieldsProps = map[string]map[string]string{"Id" : map[string]string{"optional": "1",},"Player_id" : map[string]string{"optional": "1",},"Proto_id" : map[string]string{"obscured": "","optional": "1",},"Amount" : map[string]string{"obscured": "","optional": "1",},} +var _DataItem_class_props map[string]string = map[string]string{"POD": "", "table": "item", "id": "id", "owner": "player_id", "bitfields": ""} +var _DataItem_class_fields []string = []string{"id", "player_id", "proto_id", "amount"} +var _DataItem_fields_props meta.ClassFieldsProps = map[string]map[string]string{"Id": map[string]string{"optional": "1"}, "Player_id": map[string]string{"optional": "1"}, "Proto_id": map[string]string{"obscured": "", "optional": "1"}, "Amount": map[string]string{"obscured": "", "optional": "1"}} func DataItem_CLASS_ID() uint32 { - return 263721017 + return 263721017 } type IDataItem interface { - meta.IMetaStruct - PtrDataItem() *DataItem + meta.IMetaStruct + PtrDataItem() *DataItem } func (*DataItem) CLASS_ID() uint32 { - return 263721017 + return 263721017 } func (*DataItem) CLASS_NAME() string { - return "DataItem" + return "DataItem" } func (*DataItem) CLASS_PROPS() *map[string]string { - return &_DataItem_class_props + return &_DataItem_class_props } func (*DataItem) CLASS_FIELDS() []string { - return _DataItem_class_fields + return _DataItem_class_fields } func (*DataItem) CLASS_FIELDS_PROPS() *meta.ClassFieldsProps { - return &_DataItem_fields_props + return &_DataItem_fields_props } //convenience getter func PtrDataItem(m meta.IMetaStruct) *DataItem { - p, ok := m.(IDataItem) - if !ok { - return nil - } - return p.PtrDataItem() + p, ok := m.(IDataItem) + if !ok { + return nil + } + return p.PtrDataItem() } func (self *DataItem) PtrDataItem() *DataItem { - return self + return self } func NewDataItem() *DataItem { - item := new (DataItem) - item.Reset() - return item + item := new(DataItem) + item.Reset() + return item } func (self *DataItem) Reset() { - - self.Id = 0 - self.Player_id = 0 - self.Proto_id = 0 - self.Amount = 0 -self.fieldsMask = meta.FieldsMask{} + + self.Id = 0 + self.Player_id = 0 + self.Proto_id = 0 + self.Amount = 0 + self.fieldsMask = meta.FieldsMask{} } func (self *DataItem) Read(reader meta.Reader) error { - return meta.ReadStruct(reader, self, "") + return meta.ReadStruct(reader, self, "") } func (self *DataItem) ReadFields(reader meta.Reader) error { - self.Reset() - - use_mask, mask, err := reader.TryReadMask() + self.Reset() - if err != nil { + use_mask, mask, err := reader.TryReadMask() - return err + if err != nil { - } + return err - self.fieldsMask = mask + } - _cont_size, err := reader.GetContainerSize() - if err != nil { - return err - } - if _cont_size < 0 { - _cont_size = 0 - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(0)) { - if err := reader.ReadU32(&self.Id, "id"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(1)) { - if err := reader.ReadU32(&self.Player_id, "player_id"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(2)) { - if err := reader.ReadU32(&self.Proto_id, "proto_id"); err != nil { return /*optional*/nil } - } - if _cont_size <= 0 { - return nil - } - if !use_mask { - _cont_size-- - } - if !use_mask || (use_mask && self.HasValue(3)) { - if err := reader.ReadI64(&self.Amount, "amount"); err != nil { return /*optional*/nil } - } - return nil + self.fieldsMask = mask + + _cont_size, err := reader.GetContainerSize() + if err != nil { + return err + } + if _cont_size < 0 { + _cont_size = 0 + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(0)) { + if err := reader.ReadU32(&self.Id, "id"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(1)) { + if err := reader.ReadU32(&self.Player_id, "player_id"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(2)) { + if err := reader.ReadU32(&self.Proto_id, "proto_id"); err != nil { + return /*optional*/ nil + } + } + if _cont_size <= 0 { + return nil + } + if !use_mask { + _cont_size-- + } + if !use_mask || (use_mask && self.HasValue(3)) { + if err := reader.ReadI64(&self.Amount, "amount"); err != nil { + return /*optional*/ nil + } + } + return nil } func (self *DataItem) Write(writer meta.Writer) error { - return meta.WriteStruct(writer, self, "") + return meta.WriteStruct(writer, self, "") } func (self *DataItem) WriteFields(writer meta.Writer) error { - - if err := writer.WriteU32(self.Id, "id"); err != nil { return err } - if err := writer.WriteU32(self.Player_id, "player_id"); err != nil { return err } + if err := writer.WriteU32(self.Id, "id"); err != nil { + return err + } - if err := writer.WriteU32(self.Proto_id, "proto_id"); err != nil { return err } + if err := writer.WriteU32(self.Player_id, "player_id"); err != nil { + return err + } - if err := writer.WriteI64(self.Amount, "amount"); err != nil { return err } + if err := writer.WriteU32(self.Proto_id, "proto_id"); err != nil { + return err + } - return nil + if err := writer.WriteI64(self.Amount, "amount"); err != nil { + return err + } + + return nil } -func(self *DataItem) HasValue(index uint64) bool { - return self.fieldsMask.FieldChanged(index) +func (self *DataItem) HasValue(index uint64) bool { + return self.fieldsMask.FieldChanged(index) } -func(self *DataItem) SetFieldChanged(index uint64) { - self.fieldsMask.SetFieldChanged(index) +func (self *DataItem) SetFieldChanged(index uint64) { + self.fieldsMask.SetFieldChanged(index) } -func(self *DataItem) IsMaskFilled() bool { - return self.fieldsMask.IsFilled() +func (self *DataItem) IsMaskFilled() bool { + return self.fieldsMask.IsFilled() } -func(self *DataItem) GetMask() meta.FieldsMask { - return self.fieldsMask +func (self *DataItem) GetMask() meta.FieldsMask { + return self.fieldsMask } func (self *DataItem) NewInstance() meta.IMetaDataItem { - return NewDataItem() + return NewDataItem() } func (self *DataItem) GetDbTableName() string { - return "item" + return "item" } func (self *DataItem) GetDbFields() []string { - return self.CLASS_FIELDS() + return self.CLASS_FIELDS() } func (self *DataItem) GetOwnerFieldName() string { - return "player_id" + return "player_id" } func (self *DataItem) GetIdFieldName() string { - return "id" + return "id" } func (self *DataItem) GetIdValue() uint64 { - return uint64(self.Id) + return uint64(self.Id) } func (self *DataItem) Import(data interface{}) { - switch data.(type) { - case DataItem: - { - - row := data.(DataItem) - self.Id = row.Id - self.Player_id = row.Player_id - self.Proto_id = row.Proto_id - self.Amount = row.Amount - break - } - default: - break - } + switch data.(type) { + case DataItem: + { + + row := data.(DataItem) + self.Id = row.Id + self.Player_id = row.Player_id + self.Proto_id = row.Proto_id + self.Amount = row.Amount + break + } + default: + break + } } func (self *DataItem) Export(data []interface{}) { - - data[0] = self.Id - data[1] = self.Player_id - data[2] = self.Proto_id - data[3] = self.Amount -} + data[0] = self.Id + data[1] = self.Player_id + data[2] = self.Proto_id + data[3] = self.Amount +}