go-xorm / xorm

Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm
BSD 3-Clause "New" or "Revised" License
6.67k stars 757 forks source link

能否增加对postgresql的数组类型支持? #396

Open dxvgef opened 8 years ago

dxvgef commented 8 years ago

xorm现在用的好像是lib/pq这个包,也是无法支持读取数组类型字段的,我测了jackc/pgx这个包是支持的,也支持json/jsonb类型,是否考虑在xorm中用pgx这个包替换lib/pq?两个包的使用方法几乎是一样的,而且pgx里还有pgx.NullInt16,pgx.NullInt32,pgx.NullInt64等类型。

lunny commented 8 years ago

可以考虑。

dxvgef commented 8 years ago

大概什么时候可以支持呢?我刚才试了一下pgx的stdlib这个包只是个基本的驱动,对array类型的支持还是在pgx里实现的,所以只能参考无法直接用pgx/stdlib替换lib/pq了

xtudouh commented 8 years ago

其实这个只需要开放一个类型扩展就好了,像postgresql里面的各种数组,只需要开放一个接口供大家实现就可以了,举个例子,我这边有个业务是要查询数组的,最终输出结果是json,我这边的解决方案是定义一个自定义的类型, 由于lib/pq查出来的原生数据是字符串类型的[]byte(可以直接理解为string类型),我这边先用string把数据接出来,然后实现json/Marshaler接口,然后把数据以json数组输出,虽然我这边目的是达到了,但ORM的字段映射有点偏下游,这样后续扩展起来比较繁琐,且可能存在重复劳动,若框架里面要是提供自定义类型扩展,允许在字段类型转换的环节直接转换成目标类型,这样实现起来会更优雅,下面是我的代码: type ArrayString string

func (s ArrayString) MarshalJSON() ([]byte, error) { str := fmt.Sprintf("%v", s) str = str[1:len(str) - 1] out := "[" for _, el := range strings.Split(str, ",") { out = fmt.Sprintf(%s"%s",, out, strings.TrimSpace(el)) } out = out[:len(out) - 1] + "]" return []byte(out), nil }

func (s ArrayString) ParseArray() []string { str := fmt.Sprintf("%v", s) str = str[1:len(str) - 1] var out []string for _, el := range strings.Split(str, ",") { out = append(out, strings.TrimSpace(el)) } return out }

lunny commented 8 years ago

http://gobook.io/read/github.com/go-xorm/manual-zh-CN/chapter-02/5.types.html

go type's kind value method xorm type implemented Conversion Conversion.ToDB / Conversion.FromDB Text

用这个接口就可以了。

xtudouh commented 8 years ago

搞定,但是里面还是有一些地方需要注意一下,自定义类型的方法只能用指针, 只能用这种,func (s ArrayString) FromDB(data []byte) error, 而不能用func (s ArrayString) FromDB(data []byte) error, 后面这一种是不能成功赋值的,非常感谢。 下面是我的代码,仅供参考: type ArrayString []string func (s ArrayString) FromDB(data []byte) error { str := fmt.Sprintf("%s", string(data)) str = str[1:len(str) - 1] var out []string for _, el := range strings.Split(str, ",") { out = append(out, strings.TrimSpace(el)) } *s = ArrayString(out) return nil }

qianxiansheng90 commented 5 years ago

请问,xorm 对 pg 数组的支持(直接映射为pg里面的数组),有完成计划吗?