gpt4 book ai didi

postgresql - sqlx postgres 扫描方法失败

转载 作者:IT王子 更新时间:2023-10-29 02:16:04 26 4
gpt4 key购买 nike

我正在尝试执行包含自定义 geoPoint 类型的 postgres 查询,但收到意外的 EOF 错误。对我做错了什么有什么想法吗?

type Account struct {
Id uint `json:"id" db:"id"`
RegistrationId string `json:"registration_id" db:"registration_id"`
PhoneNumber string `json:"phone_number" db:"phone_number"`
AuthToken string `json:"auth_token" db:"auth_token"`
// Role string `json:"-" db:"role"`
CreatedAt time.Time `json:"-" db:"created_at"`
ActivatedAt time.Time `json:"-" db:"activated_at"`

Location GeoPoint `json:"location" db:"location"`
}

// THE FAILING FUNCTION
func FindAccountByToken(db *sqlx.DB, token string) (Account, error) {
var account Account
log.Println("FindAcountByToken", token)
err := db.Get(&account, "select * from accounts where auth_token = $1", token)
return account, err
}

type GeoPoint struct {
Latitude float64 `json:"latitude" db:"latitude"`
Longitude float64 `json:"longitude" db:"longitude"`
}

// String value
func (g *GeoPoint) String() string {
return fmt.Sprintf("(%v, %v)", g.Latitude, g.Longitude)
}

// Value of the geoPoint to be stored in the db based on the .String() method
func (g GeoPoint) Value() (driver.Value, error) {
return g.String(), nil
}

// Scan converts the db []byte array value to the geoPoint value
func (g *GeoPoint) Scan(src interface{}) error {
var source []byte
var gp GeoPoint

switch src.(type) {
case []byte:
source = src.([]byte)
default:
return errors.New("Unable to perform geopoint conversion")
}

log.Println("bytes -> ", source)

reader := bytes.NewReader(source)
if err := binary.Read(reader, binary.BigEndian, &gp); err != nil {
log.Println("BinaryRead Error", err)
return err
}

*g = gp

return nil
}

最佳答案

ScannerValuer 接口(interface)的 GeoPoint 实现看起来有问题。它们应该是对称的,但在一种情况下,它将 GeoPoint 表示为形式为任意可变长度的字符串:

"(<latitude>, <longitude>)"

但在另一个方向上,需要正好 16 个字节的表示(两个 64 位 float ,大端字节顺序)。这似乎不兼容。

你测试过Value()的输出值可以反馈到Scan()得到相同的值吗?本质上,您应该能够:

p1 := GeoPoint{3.1415926, 2.71828}
bs, _ := p1.Value()
p2 := GeoPoint{}
p2.Scan(bs)
fmt.Printf("%#v\n", p2)

并在 p2 中看到与 p1 中相同的值。

例如,像这样的东西:

// Value of the geoPoint to be stored in the db
func (g *GeoPoint) Value() (driver.Value, error) {
var buf bytes.Buffer
binary.Write(&buf, binary.BigEndian, g)
return buf.Bytes(), nil
}

// Scan converts the db []byte array value to the geoPoint value
func (g *GeoPoint) Scan(src interface{}) error {
var source []byte
switch src.(type) {
case []byte:
source = src.([]byte)
default:
return errors.New("Unable to perform geopoint conversion")
}
reader := bytes.NewReader(source)
return binary.Read(reader, binary.BigEndian, g)
}

应该满足这个属性。 Scan()Value() 必须在概念上保持一致:否则,它们将毫无用处。

关于postgresql - sqlx postgres 扫描方法失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29882044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com