Как сохранить точку в базе данных postgres SQL с помощью gorm

Я пытаюсь сохранить переменную Point в базе данных SQL с помощью GORM на сервере go, я пробовал искать везде, но пока не нашел ответа, который меня удовлетворяет


person Eddi3    schedule 17.06.2016    source источник
comment
Что такое балл? Набор координат, например type Point struct{ X, Y int }? Также: почему? Что ты пробовал? Почему другие решения не удовлетворили? Вам нужно добавить больше деталей к описанию вашей проблемы.   -  person Brian Stengaard - Podio    schedule 17.06.2016
comment
В postgres SQL я могу создать столбец, содержащий точку типа, это должны быть X и Y, да, но он будет хранить lat и lng, поэтому он может не быть типом int, если только это не единственный тип, который может быть сохранен в точке в postgres sql. Я смотрел похожие сообщения об этом при переполнении стека: stackoverflow.com/questions/1727137/ Я взглянул на второй ответ, который называет создание пространственного столбца с помощью точки   -  person Eddi3    schedule 17.06.2016
comment
В основном я хочу сделать то, что было упомянуто во 2-м сообщении, используя структуру GORM, упомянутую на этом сайте: jinzhu. me / gorm / models.html   -  person Eddi3    schedule 17.06.2016


Ответы (1)


Для любого типа, который не поддерживается пакетом database/sql стандартной библиотеки или сторонним пакетом, который зависит от database/sql, например gorm, вы можете реализовать _ 4_ и _5 _ интерфейсы для добавления настраиваемой поддержки типа.

Чтобы иметь возможность правильно реализовать эти два интерфейса, вам необходимо сначала выяснить, что целевая база данных ожидает в качестве входных данных и что возвращает в качестве выходных данных для этого типа. В случае PostgreSQL и типа Point синтаксис следующий: (x,y).

Итак, вы можете сделать следующее:

  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
}
person mkopriva    schedule 25.07.2021