如何使用gorm在postgres SQL数据库中存储一个点

时间:2016-06-17 20:15:25

标签: postgresql go go-gorm

我试图在go服务器上使用GORM将Point变量存储在SQL数据库中,我试着到处寻找,但我还没有看到满足我的答案

1 个答案:

答案 0 :(得分:1)

对于标准库的 database/sql 包不支持的任何类型,也不支持依赖于 database/sql 的第 3 方包,例如 gorm,您可以实现 {{3 }} 和 Valuer 接口来添加对类型的自定义支持。

为了能够正确实现这两个接口,您首先需要找出目标数据库期望什么作为输入以及它返回什么作为该类型的输出。在 PostgreSQL 和 Point 类型的情况下,语法是 Scanner

所以你可以做的是:

  1. 声明类型。
type Point struct {
    X, Y float64
}
  1. 实现 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
}
  1. 实现扫描仪接口。
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
}