1 回答
TA贡献2037条经验 获得超6个赞
我们总是conn.*Typed()在我们的项目中使用查询来做到这一点。
首先,您需要在 Tarantool 中定义表示元组的结构。然后你需要为它实现两个接口,msgpack.CustomDecoder和msgpack.CustomEncoder。
你应该能够做这样的事情:
type Session struct {
ID string
UserID int64
}
func (s *Session) EncodeMsgpack(e *msgpack.Encoder) error {
if err := e.EncodeArrayLen(2); err != nil {
return err
}
if err := e.EncodeString(s.ID); err != nil {
return err
}
if err := e.EncodeInt64(s.UserID); err != nil {
return err
}
return nil
}
func (s *Session) DecodeMsgpack(d *msgpack.Decoder) error {
l, err := d.DecodeArrayLen()
if err != nil {
return err
}
decodedFields := 1
if s.ID, err = d.DecodeString(); err != nil || decodedFields == l {
return err
}
decodedFields++
if s.UserID, err = d.DecodeInt64(); err != nil || decodedFields == l {
return err
}
for i := 0; i < l-decodedFields; i++ {
_ = d.Skip()
}
return nil
}
注意解码器。它包含计数字段。这对于非中断迁移是必要的。
例如,如果 msgpack 数组的字段数少于我们尝试解码的字段数,则不会出现任何问题。
选择查询的响应是 msgpack 元组的顺序数组,因此如果我们不跳过未知字段,则结构的下一个实例的解码将不会从下一个元组的开头开始。
然后你可以尝试做查询:
func() ([]Session, error) {
const userID = 822
var sessions []Session
err := conn.SelectTyped("session", "user", 0, 10, tarantool.IterEq, []interface{}{userID}, &resp)
if err != nil {
return nil, err
}
if len(resp) == 0 {
return nil, nil
}
return sessions, nil
}
在我看来,这是最好的方法,因为反射、类型转换和类型断言最少,如果使用不慎,可能会导致生产中的恐慌。这也是一种性能更高的方式。
- 1 回答
- 0 关注
- 95 浏览
添加回答
举报