xorm的sql builder

最近在使用xorm,并使用了sql builder来构建sql查询没想到升级后原来可以使用的代码居然报错了。

0x00 代码

sql, args, _ := builder.Select("*").
        From("user").
        Where(builder.Eq{"uid": 1}).
        ToSQL()
res, err := orm.QueryString(sql, args...)

0x01 对比

发现xorm在0.6.3 和 0.6.4间做了改动,如图
0.6.3
359523-20180118111057209-1961695913.png

0.6.4
359523-20180118110957396-1877404019.png

原来如此,去掉了第一个参数,改为全部可变参数了,于是机智的把args...,改为了args
关于可变参数的问题,可以参考我的这篇文章

0x02 新错误

没想到编译没错,运行时报错了,提示

sql: converting argument $1 type: unsupported type []interface {}, a slice of interface

即类型错误。继续追踪代码,发现session_query.go里有生成sql的函数,代码如下:

func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
    if len(sqlorArgs) > 0 {
        return sqlorArgs[0].(string), sqlorArgs[1:], nil
    }
    //省略
}

由于sqlorArgs是slice,而且builder.ToSql的args也是slice,那么sqlorArgs[1:]又创建了一个新的slice,就让最后返回的slice变成了二元slice了,所以出现了上面的类型错误。

0x03 解决办法

想了一下,其实我觉得上一个版本的函数签名更好,两个参数,一个负责接受sql语句,一个负责接收sql变量。给作者提了issue,或许作者有更好的解决方案。
下面是我的临时解决方法:

func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
    if len(sqlorArgs) > 0 {
        if len(sqlorArgs) == 2 && reflect.TypeOf(sqlorArgs[1]).Kind() == reflect.Slice {
            return sqlorArgs[0].(string), sqlorArgs[1].([]interface{}), nil
        }
        return sqlorArgs[0].(string), sqlorArgs[1:], nil
    }
    //省略
}

作者已经更新,方法更加巧妙,增加了builder类型
359523-20180119084252803-1047419444.png

用法,直接传builder即可
359523-20180119084343037-1817201869.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值