I'm trying to store a Point variable in an SQL database using GORM on a go server, I tried looking everywhere but I haven't seen an answer that satisfies me yet
问问题
560 次
1 回答
3
对于标准库的包不支持的任何类型,database/sql
也不是依赖于 的 3rd 方包,您可以实现和接口以添加对该类型的自定义支持。database/sql
gorm
Valuer
Scanner
为了能够正确实现这两个接口,您首先需要找出目标数据库期望作为输入的内容以及作为该类型的输出返回的内容。对于 PostgreSQL 和 Point 类型,语法是(x,y)
.
因此,您可以执行以下操作:
- 声明类型。
type Point struct {
X, Y float64
}
- 实现 Valuer 接口。
func (p Point) Value() (driver.Value, error) {
out := []byte{'('}
out = strconv.AppendFloat(out, p.X, 'f', -1, 64)
out = append(out, ',')
out = strconv.AppendFloat(out, p.Y, 'f', -1, 64)
out = append(out, ')')
return out, nil
}
- 实现 Scanner 接口。
func (p *Point) Scan(src interface{}) (err error) {
var data []byte
switch src := src.(type) {
case []byte:
data = src
case string:
data = []byte(src)
case nil:
return nil
default:
return errors.New("(*Point).Scan: unsupported data type")
}
if len(data) == 0 {
return nil
}
data = data[1 : len(data)-1] // drop the surrounding parentheses
for i := 0; i < len(data); i++ {
if data[i] == ',' {
if p.X, err = strconv.ParseFloat(string(data[:i]), 64); err != nil {
return err
}
if p.Y, err := strconv.ParseFloat(string(data[i+1:]), 64); err != nil {
return err
}
break
}
}
return nil
}
于 2021-07-25T19:02:57.297 回答