【发布时间】:2020-06-16 15:20:09
【问题描述】:
我参考了irbanana's answer 来支持 PostGIS 的空间数据类型。我正在使用 MySQL 并尝试为自定义数据类型 EWKBGeomPoint 实现 Value()。
我的 Gorm 模型:
import (
"github.com/twpayne/go-geom"
"github.com/twpayne/go-geom/encoding/ewkb"
)
type EWKBGeomPoint geom.Point
type Tag struct {
Name string `json:"name"`
json:"siteID"` // forign key
Loc EWKBGeomPoint `json:"loc"`
}
据我所知,MySQL 支持这样的插入:
INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name',ST_GeomFromText('POINT(10.000000 20.000000)'))
或
INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name', ST_GeomFromWKB(X'0101000000000000000000F03F000000000000F03F'))
如果我自己做一个Value() 来满足database/sql 的Valuer 接口:
func (g EWKBGeomPoint) Value() (driver.Value, error) {
log.Println("EWKBGeomPoint value called")
b := geom.Point(g)
bp := &b
floatArr := bp.Coords()
return fmt.Sprintf("ST_GeomFromText('POINT(%f %f)')", floatArr[0], floatArr[1]), nil
}
包括ST_GeomFromText() 在内的整个值被Gorm 单引号引用,因此它不起作用:
INSERT INTO `tag` (`name`,`loc`) VALUES ('tag name','ST_GeomFromText('POINT(10.000000 20.000000)')');
如何让它发挥作用?
编辑 1:
我追踪到 Gorm 代码,最终到达 callback_create.go 的 createCallback 函数。在里面检查if primaryField == nil,这是真的,它会调用scope.SQLDB().Exec,然后我没有进一步追踪。
scope.SQL 是字符串INSERT INTOtag(name,loc) VALUES (?,?) 和scope.SQLVars 打印[tag name {{1 2 [10 20] 0}}]。看起来插值发生在这个调用中。
这是调用database/sql 代码吗?
编辑 2:
发现了一个类似的 Stackoverflow 问题here。但我不明白解决方案。
【问题讨论】:
-
你能用raw sql吗?
-
@Mark 我可以,但我绝对不想。我有一个已经定义了 CRUD 的 REST 服务。如果这按我认为应该的方式工作,那么一旦我定义了模式,就不需要为每个表复制所有端点处理程序,并且编组/解编组到 JSON 和从 JSON 编组只是一个小工作。
-
为什么原始
SELECT LAST_INSERT_ID()不满足将 auto_inc 用于原始查询的要求?它与连接绑定,因此不会受到其他连接的干扰。 -
GORM 是否无法“转义”引号,以便您可以嵌套引号?无论如何,在大多数(如果不是全部)MySQL 语法情况下,单引号和双引号是可以互换的。这提供了 2 层而不需要任何转义。
-
@RickJames 我认为嵌套引用不起作用。 db 函数根本不应该被引用。你说得对
last_insert_id()我并不精通SQL。谢谢你的小费。 :)