Merge branch 'builder'

This commit is contained in:
Lunny Xiao 2016-09-21 14:45:28 +08:00
commit bcc1d3eb5a
8 changed files with 253 additions and 360 deletions

View File

@ -30,6 +30,7 @@ The last master version is not backwards compatible. You should use `engine.Show
* Optimistic Locking support * Optimistic Locking support
* SQL Builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder)
# Drivers Support # Drivers Support
@ -51,10 +52,15 @@ Drivers for Go's sql package which currently support database/sql includes:
* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment) * Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment)
* ql: [github.com/cznic/ql](https://github.com/cznic/ql) (experiment)
# Changelog # Changelog
* **v0.6.0**
* remove support for ql
* add query condition builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder), so `Where`, `And`, `Or`
methods can use `builder.Cond` as parameter
* add Sum, SumInt, SumInt64 and NotIn methods
* some bugs fixed
* **v0.5.0** * **v0.5.0**
* logging interface changed * logging interface changed
* some bugs fixed * some bugs fixed
@ -234,6 +240,13 @@ counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user // SELECT count(*) AS total FROM user
``` ```
* Query conditions builder
```Go
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
``
# Cases # Cases
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader) * [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)

View File

@ -32,6 +32,8 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
* 支持记录版本(即乐观锁) * 支持记录版本(即乐观锁)
* 内置SQL Builder支持
## 驱动支持 ## 驱动支持
目前支持的Go数据库驱动和对应的数据库如下 目前支持的Go数据库驱动和对应的数据库如下
@ -52,10 +54,15 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持) * Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (试验性支持)
* ql: [github.com/cznic/ql](https://github.com/cznic/ql) (试验性支持)
## 更新日志 ## 更新日志
* **v0.6.0**
* 去除对 ql 的支持
* 新增条件查询分析器 [github.com/go-xorm/builder](https://github.com/go-xorm/builder), 从因此 `Where, And, Or` 函数
将可以用 `builder.Cond` 作为条件组合
* 新增 Sum, SumInt, SumInt64 和 NotIn 函数
* Bug修正
* **v0.5.0** * **v0.5.0**
* logging接口进行不兼容改变 * logging接口进行不兼容改变
* Bug修正 * Bug修正
@ -234,6 +241,13 @@ counts, err := engine.Count(&user)
// SELECT count(*) AS total FROM user // SELECT count(*) AS total FROM user
``` ```
* 条件编辑器
```Go
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
``
# 案例 # 案例
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader) * [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)

View File

@ -1 +1 @@
xorm v0.5.6.0921 xorm v0.6.0.0921

View File

@ -641,10 +641,10 @@ func (engine *Engine) Cascade(trueOrFalse ...bool) *Session {
} }
// Where method provide a condition query // Where method provide a condition query
func (engine *Engine) Where(querystring string, args ...interface{}) *Session { func (engine *Engine) Where(query interface{}, args ...interface{}) *Session {
session := engine.NewSession() session := engine.NewSession()
session.IsAutoClose = true session.IsAutoClose = true
return session.Where(querystring, args...) return session.Where(query, args...)
} }
// Id will be depracated, please use ID instead // Id will be depracated, please use ID instead

View File

@ -41,7 +41,7 @@ func newRows(session *Session, bean interface{}) (*Rows, error) {
} }
if rows.session.Statement.RawSQL == "" { if rows.session.Statement.RawSQL == "" {
sqlStr, args = rows.session.Statement.genGetSql(bean) sqlStr, args = rows.session.Statement.genGetSQL(bean)
} else { } else {
sqlStr = rows.session.Statement.RawSQL sqlStr = rows.session.Statement.RawSQL
args = rows.session.Statement.RawParams args = rows.session.Statement.RawParams

View File

@ -16,6 +16,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/go-xorm/builder"
"github.com/go-xorm/core" "github.com/go-xorm/core"
) )
@ -112,7 +113,7 @@ func (session *Session) Prepare() *Session {
return session return session
} }
// Sql will be deprecated, please use SQL instead. // Sql !DEPRECIATED! will be deprecated, please use SQL instead.
func (session *Session) Sql(querystring string, args ...interface{}) *Session { func (session *Session) Sql(querystring string, args ...interface{}) *Session {
session.Statement.Sql(querystring, args...) session.Statement.Sql(querystring, args...)
return session return session
@ -126,20 +127,20 @@ func (session *Session) SQL(querystring string, args ...interface{}) *Session {
} }
// Where provides custom query condition. // Where provides custom query condition.
func (session *Session) Where(querystring string, args ...interface{}) *Session { func (session *Session) Where(query interface{}, args ...interface{}) *Session {
session.Statement.Where(querystring, args...) session.Statement.Where(query, args...)
return session return session
} }
// And provides custom query condition. // And provides custom query condition.
func (session *Session) And(querystring string, args ...interface{}) *Session { func (session *Session) And(query interface{}, args ...interface{}) *Session {
session.Statement.And(querystring, args...) session.Statement.And(query, args...)
return session return session
} }
// Or provides custom query condition. // Or provides custom query condition.
func (session *Session) Or(querystring string, args ...interface{}) *Session { func (session *Session) Or(query interface{}, args ...interface{}) *Session {
session.Statement.Or(querystring, args...) session.Statement.Or(query, args...)
return session return session
} }
@ -189,6 +190,12 @@ func (session *Session) In(column string, args ...interface{}) *Session {
return session return session
} }
// NotIn provides a query string like "id in (1, 2, 3)"
func (session *Session) NotIn(column string, args ...interface{}) *Session {
session.Statement.NotIn(column, args...)
return session
}
// Incr provides a query string like "count = count + 1" // Incr provides a query string like "count = count + 1"
func (session *Session) Incr(column string, arg ...interface{}) *Session { func (session *Session) Incr(column string, arg ...interface{}) *Session {
session.Statement.Incr(column, arg...) session.Statement.Incr(column, arg...)
@ -688,7 +695,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
for _, filter := range session.Engine.dialect.Filters() { for _, filter := range session.Engine.dialect.Filters() {
sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable) sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable)
} }
newsql := session.Statement.convertIdSql(sqlStr) newsql := session.Statement.convertIDSQL(sqlStr)
if newsql == "" { if newsql == "" {
return false, ErrCacheFailed return false, ErrCacheFailed
} }
@ -789,7 +796,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable) sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable)
} }
newsql := session.Statement.convertIdSql(sqlStr) newsql := session.Statement.convertIDSQL(sqlStr)
if newsql == "" { if newsql == "" {
return ErrCacheFailed return ErrCacheFailed
} }
@ -892,15 +899,14 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
ff = append(ff, ie[0]) ff = append(ff, ie[0])
} }
newSession.In(table.PrimaryKeys[0], ff...) newSession.In("`"+table.PrimaryKeys[0]+"`", ff...)
} else { } else {
var kn = make([]string, 0)
for _, name := range table.PrimaryKeys {
kn = append(kn, name+" = ?")
}
condi := "(" + strings.Join(kn, " AND ") + ")"
for _, ie := range ides { for _, ie := range ides {
newSession.Or(condi, ie...) cond := builder.NewCond()
for i, name := range table.PrimaryKeys {
cond = cond.And(builder.Eq{"`" + name + "`": ie[i]})
}
newSession.Or(cond)
} }
} }
@ -1036,7 +1042,7 @@ func (session *Session) Get(bean interface{}) (bool, error) {
return false, ErrTableNotFound return false, ErrTableNotFound
} }
session.Statement.Limit(1) session.Statement.Limit(1)
sqlStr, args = session.Statement.genGetSql(bean) sqlStr, args = session.Statement.genGetSQL(bean)
} else { } else {
sqlStr = session.Statement.RawSQL sqlStr = session.Statement.RawSQL
args = session.Statement.RawParams args = session.Statement.RawParams
@ -1087,7 +1093,7 @@ func (session *Session) Count(bean interface{}) (int64, error) {
var sqlStr string var sqlStr string
var args []interface{} var args []interface{}
if session.Statement.RawSQL == "" { if session.Statement.RawSQL == "" {
sqlStr, args = session.Statement.genCountSql(bean) sqlStr, args = session.Statement.genCountSQL(bean)
} else { } else {
sqlStr = session.Statement.RawSQL sqlStr = session.Statement.RawSQL
args = session.Statement.RawParams args = session.Statement.RawParams
@ -1119,7 +1125,7 @@ func (session *Session) Sum(bean interface{}, columnName string) (float64, error
var sqlStr string var sqlStr string
var args []interface{} var args []interface{}
if len(session.Statement.RawSQL) == 0 { if len(session.Statement.RawSQL) == 0 {
sqlStr, args = session.Statement.genSumSql(bean, columnName) sqlStr, args = session.Statement.genSumSQL(bean, columnName)
} else { } else {
sqlStr = session.Statement.RawSQL sqlStr = session.Statement.RawSQL
args = session.Statement.RawParams args = session.Statement.RawParams
@ -1151,7 +1157,7 @@ func (session *Session) Sums(bean interface{}, columnNames ...string) ([]float64
var sqlStr string var sqlStr string
var args []interface{} var args []interface{}
if len(session.Statement.RawSQL) == 0 { if len(session.Statement.RawSQL) == 0 {
sqlStr, args = session.Statement.genSumSql(bean, columnNames...) sqlStr, args = session.Statement.genSumSQL(bean, columnNames...)
} else { } else {
sqlStr = session.Statement.RawSQL sqlStr = session.Statement.RawSQL
args = session.Statement.RawParams args = session.Statement.RawParams
@ -1183,7 +1189,7 @@ func (session *Session) SumsInt(bean interface{}, columnNames ...string) ([]int6
var sqlStr string var sqlStr string
var args []interface{} var args []interface{}
if len(session.Statement.RawSQL) == 0 { if len(session.Statement.RawSQL) == 0 {
sqlStr, args = session.Statement.genSumSql(bean, columnNames...) sqlStr, args = session.Statement.genSumSQL(bean, columnNames...)
} else { } else {
sqlStr = session.Statement.RawSQL sqlStr = session.Statement.RawSQL
args = session.Statement.RawParams args = session.Statement.RawParams
@ -1240,10 +1246,13 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
var table = session.Statement.RefTable var table = session.Statement.RefTable
var addedTableName = (len(session.Statement.JoinStr) > 0) var addedTableName = (len(session.Statement.JoinStr) > 0)
var autoCond builder.Cond
if !session.Statement.noAutoCondition && len(condiBean) > 0 { if !session.Statement.noAutoCondition && len(condiBean) > 0 {
colNames, args := session.Statement.buildConditions(table, condiBean[0], true, true, false, true, addedTableName) var err error
session.Statement.ConditionStr = strings.Join(colNames, " AND ") autoCond, err = session.Statement.buildConds(table, condiBean[0], true, true, false, true, addedTableName)
session.Statement.BeanArgs = args if err != nil {
panic(err)
}
} else { } else {
// !oinume! Add "<col> IS NULL" to WHERE whatever condiBean is given. // !oinume! Add "<col> IS NULL" to WHERE whatever condiBean is given.
// See https://github.com/go-xorm/xorm/issues/179 // See https://github.com/go-xorm/xorm/issues/179
@ -1256,8 +1265,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
} }
colName = session.Engine.Quote(nm) + "." + colName colName = session.Engine.Quote(nm) + "." + colName
} }
session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL OR %v = '0001-01-01 00:00:00')", autoCond = builder.IsNull{colName}.Or(builder.Eq{colName: "0001-01-01 00:00:00"})
colName, colName)
} }
} }
@ -1291,12 +1299,10 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
} }
} }
session.Statement.attachInSql() condSQL, condArgs, _ := builder.ToSQL(session.Statement.cond.And(autoCond))
session.Statement.Params = append(append(append(session.Statement.joinArgs, session.Statement.Params...),
session.Statement.BeanArgs...), session.Statement.inParams...)
sqlStr = session.Statement.genSelectSQL(columnStr) args = append(session.Statement.joinArgs, condArgs...)
args = session.Statement.Params sqlStr = session.Statement.genSelectSQL(columnStr, condSQL)
// for mssql and use limit // for mssql and use limit
qs := strings.Count(sqlStr, "?") qs := strings.Count(sqlStr, "?")
if len(args)*2 == qs { if len(args)*2 == qs {
@ -3567,97 +3573,68 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
colNames = append(colNames, session.Engine.Quote(v.colName)+" = "+v.expr) colNames = append(colNames, session.Engine.Quote(v.colName)+" = "+v.expr)
} }
var condiColNames []string session.Statement.processIdParam()
var condiArgs []interface{}
var autoCond builder.Cond
if !session.Statement.noAutoCondition && len(condiBean) > 0 { if !session.Statement.noAutoCondition && len(condiBean) > 0 {
condiColNames, condiArgs = session.Statement.buildConditions(session.Statement.RefTable, condiBean[0], true, true, false, true, false) var err error
autoCond, err = session.Statement.buildConds(session.Statement.RefTable, condiBean[0], true, true, false, true, false)
if err != nil {
return 0, err
}
} }
var condition = ""
session.Statement.processIdParam()
st := session.Statement st := session.Statement
defer session.resetStatement() defer session.resetStatement()
if st.WhereStr != "" {
condition = fmt.Sprintf("%v", st.WhereStr)
}
if condition == "" { var sqlStr string
if len(condiColNames) > 0 { var condArgs []interface{}
condition = fmt.Sprintf("%v", strings.Join(condiColNames, " "+session.Engine.Dialect().AndStr()+" ")) var condSQL string
} cond := session.Statement.cond.And(autoCond)
} else {
if len(condiColNames) > 0 {
condition = fmt.Sprintf("(%v) %v (%v)", condition,
session.Engine.Dialect().AndStr(), strings.Join(condiColNames, " "+session.Engine.Dialect().AndStr()+" "))
}
}
var sqlStr, inSQL string
var inArgs []interface{}
doIncVer := false doIncVer := false
var verValue *reflect.Value var verValue *reflect.Value
if table != nil && table.Version != "" && session.Statement.checkVersion { if table != nil && table.Version != "" && session.Statement.checkVersion {
if condition != "" { verValue, err = table.VersionColumn().ValueOf(bean)
condition = fmt.Sprintf("WHERE (%v) %v %v = ?", condition, session.Engine.Dialect().AndStr(), if err != nil {
session.Engine.Quote(table.Version)) return 0, err
} else {
condition = fmt.Sprintf("WHERE %v = ?", session.Engine.Quote(table.Version))
}
inSQL, inArgs = session.Statement.genInSql()
if len(inSQL) > 0 {
if condition != "" {
condition += " " + session.Engine.Dialect().AndStr() + " " + inSQL
} else {
condition = "WHERE " + inSQL
} }
cond = cond.And(builder.Eq{session.Engine.Quote(table.Version): verValue.Interface()})
condSQL, condArgs, _ = builder.ToSQL(cond)
if len(condSQL) > 0 {
condSQL = "WHERE " + condSQL
} }
if st.LimitN > 0 { if st.LimitN > 0 {
condition = condition + fmt.Sprintf(" LIMIT %d", st.LimitN) condSQL = condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
} }
sqlStr = fmt.Sprintf("UPDATE %v SET %v, %v %v", sqlStr = fmt.Sprintf("UPDATE %v SET %v, %v %v",
session.Engine.Quote(session.Statement.TableName()), session.Engine.Quote(session.Statement.TableName()),
strings.Join(colNames, ", "), strings.Join(colNames, ", "),
session.Engine.Quote(table.Version)+" = "+session.Engine.Quote(table.Version)+" + 1", session.Engine.Quote(table.Version)+" = "+session.Engine.Quote(table.Version)+" + 1",
condition) condSQL)
verValue, err = table.VersionColumn().ValueOf(bean)
if err != nil {
return 0, err
}
condiArgs = append(condiArgs, verValue.Interface())
doIncVer = true doIncVer = true
} else { } else {
if condition != "" { condSQL, condArgs, _ = builder.ToSQL(cond)
condition = "WHERE " + condition if len(condSQL) > 0 {
} condSQL = "WHERE " + condSQL
inSQL, inArgs = session.Statement.genInSql()
if len(inSQL) > 0 {
if condition != "" {
condition += " " + session.Engine.Dialect().AndStr() + " " + inSQL
} else {
condition = "WHERE " + inSQL
}
} }
if st.LimitN > 0 { if st.LimitN > 0 {
condition = condition + fmt.Sprintf(" LIMIT %d", st.LimitN) condSQL = condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
} }
sqlStr = fmt.Sprintf("UPDATE %v SET %v %v", sqlStr = fmt.Sprintf("UPDATE %v SET %v %v",
session.Engine.Quote(session.Statement.TableName()), session.Engine.Quote(session.Statement.TableName()),
strings.Join(colNames, ", "), strings.Join(colNames, ", "),
condition) condSQL)
} }
args = append(args, st.Params...) res, err := session.exec(sqlStr, append(args, condArgs...)...)
args = append(args, inArgs...)
args = append(args, condiArgs...)
res, err := session.exec(sqlStr, args...)
if err != nil { if err != nil {
return 0, err return 0, err
} else if doIncVer { } else if doIncVer {
@ -3716,7 +3693,7 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable) sqlStr = filter.Do(sqlStr, session.Engine.dialect, session.Statement.RefTable)
} }
newsql := session.Statement.convertIdSql(sqlStr) newsql := session.Statement.convertIDSQL(sqlStr)
if newsql == "" { if newsql == "" {
return ErrCacheFailed return ErrCacheFailed
} }
@ -3791,41 +3768,27 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
} }
// -- // --
var colNames []string var autoCond builder.Cond
var args []interface{}
if !session.Statement.noAutoCondition { if !session.Statement.noAutoCondition {
colNames, args = session.Statement.buildConditions(table, bean, true, true, false, true, false) var err error
autoCond, err = session.Statement.buildConds(table, bean, true, true, false, true, false)
if err != nil {
return 0, err
}
} }
var condition = ""
var andStr = session.Engine.dialect.AndStr()
session.Statement.processIdParam() session.Statement.processIdParam()
if session.Statement.WhereStr != "" {
condition = session.Statement.WhereStr condSQL, condArgs, _ := builder.ToSQL(session.Statement.cond.And(autoCond))
if len(colNames) > 0 { if len(condSQL) == 0 && session.Statement.LimitN == 0 {
condition += " " + andStr + " " + strings.Join(colNames, " "+andStr+" ")
}
} else {
condition = strings.Join(colNames, " "+andStr+" ")
}
inSQL, inArgs := session.Statement.genInSql()
if len(inSQL) > 0 {
if len(condition) > 0 {
condition += " " + andStr + " "
}
condition += inSQL
args = append(args, inArgs...)
}
if len(condition) == 0 && session.Statement.LimitN == 0 {
return 0, ErrNeedDeletedCond return 0, ErrNeedDeletedCond
} }
var deleteSQL, realSQL string var deleteSQL, realSQL string
var tableName = session.Engine.Quote(session.Statement.TableName()) var tableName = session.Engine.Quote(session.Statement.TableName())
if len(condition) > 0 { if len(condSQL) > 0 {
deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condition) deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL)
} else { } else {
deleteSQL = fmt.Sprintf("DELETE FROM %v", tableName) deleteSQL = fmt.Sprintf("DELETE FROM %v", tableName)
} }
@ -3842,14 +3805,14 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
switch session.Engine.dialect.DBType() { switch session.Engine.dialect.DBType() {
case core.POSTGRES: case core.POSTGRES:
inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL) inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL)
if len(condition) > 0 { if len(condSQL) > 0 {
deleteSQL += " AND " + inSQL deleteSQL += " AND " + inSQL
} else { } else {
deleteSQL += " WHERE " + inSQL deleteSQL += " WHERE " + inSQL
} }
case core.SQLITE: case core.SQLITE:
inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL) inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL)
if len(condition) > 0 { if len(condSQL) > 0 {
deleteSQL += " AND " + inSQL deleteSQL += " AND " + inSQL
} else { } else {
deleteSQL += " WHERE " + inSQL deleteSQL += " WHERE " + inSQL
@ -3862,34 +3825,34 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
} }
} }
argsForCache := make([]interface{}, 0, len(args)*2) argsForCache := make([]interface{}, 0, len(condArgs)*2)
if session.Statement.unscoped || table.DeletedColumn() == nil { // tag "deleted" is disabled if session.Statement.unscoped || table.DeletedColumn() == nil { // tag "deleted" is disabled
realSQL = deleteSQL realSQL = deleteSQL
copy(argsForCache, args) copy(argsForCache, condArgs)
argsForCache = append(session.Statement.Params, argsForCache...) argsForCache = append(condArgs, argsForCache...)
} else { } else {
// !oinume! sqlStrForCache and argsForCache is needed to behave as executing "DELETE FROM ..." for cache. // !oinume! sqlStrForCache and argsForCache is needed to behave as executing "DELETE FROM ..." for cache.
copy(argsForCache, args) copy(argsForCache, condArgs)
argsForCache = append(session.Statement.Params, argsForCache...) argsForCache = append(condArgs, argsForCache...)
deletedColumn := table.DeletedColumn() deletedColumn := table.DeletedColumn()
realSQL = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v", realSQL = fmt.Sprintf("UPDATE %v SET %v = ? WHERE %v",
session.Engine.Quote(session.Statement.TableName()), session.Engine.Quote(session.Statement.TableName()),
session.Engine.Quote(deletedColumn.Name), session.Engine.Quote(deletedColumn.Name),
condition) condSQL)
if len(orderSQL) > 0 { if len(orderSQL) > 0 {
switch session.Engine.dialect.DBType() { switch session.Engine.dialect.DBType() {
case core.POSTGRES: case core.POSTGRES:
inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL) inSQL := fmt.Sprintf("ctid IN (SELECT ctid FROM %s%s)", tableName, orderSQL)
if len(condition) > 0 { if len(condSQL) > 0 {
realSQL += " AND " + inSQL realSQL += " AND " + inSQL
} else { } else {
realSQL += " WHERE " + inSQL realSQL += " WHERE " + inSQL
} }
case core.SQLITE: case core.SQLITE:
inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL) inSQL := fmt.Sprintf("rowid IN (SELECT rowid FROM %s%s)", tableName, orderSQL)
if len(condition) > 0 { if len(condSQL) > 0 {
realSQL += " AND " + inSQL realSQL += " AND " + inSQL
} else { } else {
realSQL += " WHERE " + inSQL realSQL += " WHERE " + inSQL
@ -3903,12 +3866,12 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
} }
// !oinume! Insert NowTime to the head of session.Statement.Params // !oinume! Insert NowTime to the head of session.Statement.Params
session.Statement.Params = append(session.Statement.Params, "") condArgs = append(condArgs, "")
paramsLen := len(session.Statement.Params) paramsLen := len(condArgs)
copy(session.Statement.Params[1:paramsLen], session.Statement.Params[0:paramsLen-1]) copy(condArgs[1:paramsLen], condArgs[0:paramsLen-1])
val, t := session.Engine.NowTime2(deletedColumn.SQLType.Name) val, t := session.Engine.NowTime2(deletedColumn.SQLType.Name)
session.Statement.Params[0] = val condArgs[0] = val
var colName = deletedColumn.Name var colName = deletedColumn.Name
session.afterClosures = append(session.afterClosures, func(bean interface{}) { session.afterClosures = append(session.afterClosures, func(bean interface{}) {
@ -3917,13 +3880,11 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
}) })
} }
args = append(session.Statement.Params, args...)
if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache { if cacher := session.Engine.getCacher2(session.Statement.RefTable); cacher != nil && session.Statement.UseCache {
session.cacheDelete(deleteSQL, argsForCache...) session.cacheDelete(deleteSQL, argsForCache...)
} }
res, err := session.exec(realSQL, args...) res, err := session.exec(realSQL, condArgs...)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -14,14 +14,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/go-xorm/builder"
"github.com/go-xorm/core" "github.com/go-xorm/core"
) )
type inParam struct {
colName string
args []interface{}
}
type incrParam struct { type incrParam struct {
colName string colName string
arg interface{} arg interface{}
@ -43,10 +39,7 @@ type Statement struct {
Engine *Engine Engine *Engine
Start int Start int
LimitN int LimitN int
WhereStr string
IdParam *core.PK IdParam *core.PK
Params []interface{}
inParams []interface{}
OrderStr string OrderStr string
JoinStr string JoinStr string
joinArgs []interface{} joinArgs []interface{}
@ -57,7 +50,6 @@ type Statement struct {
columnMap map[string]bool columnMap map[string]bool
useAllCols bool useAllCols bool
OmitStr string OmitStr string
ConditionStr string
AltTableName string AltTableName string
tableName string tableName string
RawSQL string RawSQL string
@ -66,7 +58,6 @@ type Statement struct {
UseAutoJoin bool UseAutoJoin bool
StoreEngine string StoreEngine string
Charset string Charset string
BeanArgs []interface{}
UseCache bool UseCache bool
UseAutoTime bool UseAutoTime bool
noAutoCondition bool noAutoCondition bool
@ -78,10 +69,10 @@ type Statement struct {
unscoped bool unscoped bool
mustColumnMap map[string]bool mustColumnMap map[string]bool
nullableMap map[string]bool nullableMap map[string]bool
inColumns map[string]*inParam
incrColumns map[string]incrParam incrColumns map[string]incrParam
decrColumns map[string]decrParam decrColumns map[string]decrParam
exprColumns map[string]exprParam exprColumns map[string]exprParam
cond builder.Cond
} }
// Init reset all the statment's fields // Init reset all the statment's fields
@ -89,9 +80,6 @@ func (statement *Statement) Init() {
statement.RefTable = nil statement.RefTable = nil
statement.Start = 0 statement.Start = 0
statement.LimitN = 0 statement.LimitN = 0
statement.WhereStr = ""
statement.Params = make([]interface{}, 0)
statement.inParams = make([]interface{}, 0)
statement.OrderStr = "" statement.OrderStr = ""
statement.UseCascade = true statement.UseCascade = true
statement.JoinStr = "" statement.JoinStr = ""
@ -101,13 +89,11 @@ func (statement *Statement) Init() {
statement.ColumnStr = "" statement.ColumnStr = ""
statement.OmitStr = "" statement.OmitStr = ""
statement.columnMap = make(map[string]bool) statement.columnMap = make(map[string]bool)
statement.ConditionStr = ""
statement.AltTableName = "" statement.AltTableName = ""
statement.tableName = "" statement.tableName = ""
statement.IdParam = nil statement.IdParam = nil
statement.RawSQL = "" statement.RawSQL = ""
statement.RawParams = make([]interface{}, 0) statement.RawParams = make([]interface{}, 0)
statement.BeanArgs = make([]interface{}, 0)
statement.UseCache = true statement.UseCache = true
statement.UseAutoTime = true statement.UseAutoTime = true
statement.noAutoCondition = false statement.noAutoCondition = false
@ -121,10 +107,10 @@ func (statement *Statement) Init() {
statement.nullableMap = make(map[string]bool) statement.nullableMap = make(map[string]bool)
statement.checkVersion = true statement.checkVersion = true
statement.unscoped = false statement.unscoped = false
statement.inColumns = make(map[string]*inParam)
statement.incrColumns = make(map[string]incrParam) statement.incrColumns = make(map[string]incrParam)
statement.decrColumns = make(map[string]decrParam) statement.decrColumns = make(map[string]decrParam)
statement.exprColumns = make(map[string]exprParam) statement.exprColumns = make(map[string]exprParam)
statement.cond = builder.NewCond()
} }
// NoAutoCondition if you do not want convert bean's field as query condition, then use this function // NoAutoCondition if you do not want convert bean's field as query condition, then use this function
@ -136,6 +122,12 @@ func (statement *Statement) NoAutoCondition(no ...bool) *Statement {
return statement return statement
} }
// Alias set the table alias
func (statement *Statement) Alias(alias string) *Statement {
statement.TableAlias = alias
return statement
}
// Sql add the raw sql statement // Sql add the raw sql statement
func (statement *Statement) Sql(querystring string, args ...interface{}) *Statement { func (statement *Statement) Sql(querystring string, args ...interface{}) *Statement {
statement.RawSQL = querystring statement.RawSQL = querystring
@ -143,52 +135,71 @@ func (statement *Statement) Sql(querystring string, args ...interface{}) *Statem
return statement return statement
} }
// Alias set the table alias
func (statement *Statement) Alias(alias string) *Statement {
statement.TableAlias = alias
return statement
}
// Where add Where statment // Where add Where statment
func (statement *Statement) Where(querystring string, args ...interface{}) *Statement { func (statement *Statement) Where(query interface{}, args ...interface{}) *Statement {
// The second where will be triggered as And return statement.And(query, args...)
if len(statement.WhereStr) > 0 {
return statement.And(querystring, args...)
}
if !strings.Contains(querystring, statement.Engine.dialect.EqStr()) {
querystring = strings.Replace(querystring, "=", statement.Engine.dialect.EqStr(), -1)
}
statement.WhereStr = querystring
statement.Params = args
return statement
} }
// And add Where & and statment // And add Where & and statment
func (statement *Statement) And(querystring string, args ...interface{}) *Statement { func (statement *Statement) And(query interface{}, args ...interface{}) *Statement {
if len(statement.WhereStr) > 0 { switch query.(type) {
var buf bytes.Buffer case string:
fmt.Fprintf(&buf, "(%v) %s (%v)", statement.WhereStr, cond := builder.Expr(query.(string), args...)
statement.Engine.dialect.AndStr(), querystring) statement.cond = statement.cond.And(cond)
statement.WhereStr = buf.String() case builder.Cond:
} else { cond := query.(builder.Cond)
statement.WhereStr = querystring statement.cond = statement.cond.And(cond)
for _, v := range args {
if vv, ok := v.(builder.Cond); ok {
statement.cond = statement.cond.And(vv)
} }
statement.Params = append(statement.Params, args...) }
default:
// TODO: not support condition type
}
return statement return statement
} }
// Or add Where & Or statment // Or add Where & Or statment
func (statement *Statement) Or(querystring string, args ...interface{}) *Statement { func (statement *Statement) Or(query interface{}, args ...interface{}) *Statement {
if len(statement.WhereStr) > 0 { switch query.(type) {
var buf bytes.Buffer case string:
fmt.Fprintf(&buf, "(%v) %s (%v)", statement.WhereStr, cond := builder.Expr(query.(string), args...)
statement.Engine.dialect.OrStr(), querystring) statement.cond = statement.cond.Or(cond)
statement.WhereStr = buf.String() case builder.Cond:
} else { cond := query.(builder.Cond)
statement.WhereStr = querystring statement.cond = statement.cond.Or(cond)
for _, v := range args {
if vv, ok := v.(builder.Cond); ok {
statement.cond = statement.cond.Or(vv)
} }
statement.Params = append(statement.Params, args...) }
default:
// TODO: not support condition type
}
return statement
}
// In generate "Where column IN (?) " statment
func (statement *Statement) In(column string, args ...interface{}) *Statement {
if len(args) == 0 {
return statement
}
in := builder.In(column, args...)
statement.cond = statement.cond.And(in)
return statement
}
// NotIn generate "Where column IN (?) " statment
func (statement *Statement) NotIn(column string, args ...interface{}) *Statement {
if len(args) == 0 {
return statement
}
in := builder.NotIn(column, args...)
statement.cond = statement.cond.And(in)
return statement return statement
} }
@ -459,13 +470,11 @@ func (statement *Statement) colName(col *core.Column, tableName string) string {
return statement.Engine.Quote(col.Name) return statement.Engine.Quote(col.Name)
} }
// Auto generating conditions according a struct func buildConds(engine *Engine, table *core.Table, bean interface{},
func buildConditions(engine *Engine, table *core.Table, bean interface{},
includeVersion bool, includeUpdated bool, includeNil bool, includeVersion bool, includeUpdated bool, includeNil bool,
includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool, includeAutoIncr bool, allUseBool bool, useAllCols bool, unscoped bool,
mustColumnMap map[string]bool, tableName, aliasName string, addedTableName bool) ([]string, []interface{}) { mustColumnMap map[string]bool, tableName, aliasName string, addedTableName bool) (builder.Cond, error) {
var colNames []string var conds []builder.Cond
var args = make([]interface{}, 0)
for _, col := range table.Columns() { for _, col := range table.Columns() {
if !includeVersion && col.IsVersion { if !includeVersion && col.IsVersion {
continue continue
@ -502,8 +511,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
} }
if col.IsDeleted && !unscoped { // tag "deleted" is enabled if col.IsDeleted && !unscoped { // tag "deleted" is enabled
colNames = append(colNames, fmt.Sprintf("(%v IS NULL OR %v = '0001-01-01 00:00:00')", conds = append(conds, builder.IsNull{colName}.Or(builder.Eq{colName: "0001-01-01 00:00:00"}))
colName, colName))
} }
fieldValue := *fieldValuePtr fieldValue := *fieldValuePtr
@ -524,8 +532,7 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
if fieldType.Kind() == reflect.Ptr { if fieldType.Kind() == reflect.Ptr {
if fieldValue.IsNil() { if fieldValue.IsNil() {
if includeNil { if includeNil {
args = append(args, nil) conds = append(conds, builder.Eq{colName: nil})
colNames = append(colNames, fmt.Sprintf("%v %s ?", colName, engine.dialect.EqStr()))
} }
continue continue
} else if !fieldValue.IsValid() { } else if !fieldValue.IsValid() {
@ -668,17 +675,10 @@ func buildConditions(engine *Engine, table *core.Table, bean interface{},
val = fieldValue.Interface() val = fieldValue.Interface()
} }
args = append(args, val) conds = append(conds, builder.Eq{colName: val})
var condi string
if col.IsPrimaryKey && engine.dialect.DBType() == "ql" {
condi = "id() == ?"
} else {
condi = fmt.Sprintf("%v %s ?", colName, engine.dialect.EqStr())
}
colNames = append(colNames, condi)
} }
return colNames, args return builder.And(conds...), nil
} }
// TableName return current tableName // TableName return current tableName
@ -762,70 +762,6 @@ func (statement *Statement) getExpr() map[string]exprParam {
return statement.exprColumns return statement.exprColumns
} }
// In generate "Where column IN (?) " statment
func (statement *Statement) In(column string, args ...interface{}) *Statement {
length := len(args)
if length == 0 {
return statement
}
k := strings.ToLower(column)
var newargs []interface{}
if length == 1 &&
reflect.TypeOf(args[0]).Kind() == reflect.Slice {
newargs = make([]interface{}, 0)
v := reflect.ValueOf(args[0])
for i := 0; i < v.Len(); i++ {
newargs = append(newargs, v.Index(i).Interface())
}
} else {
newargs = args
}
if _, ok := statement.inColumns[k]; ok {
statement.inColumns[k].args = append(statement.inColumns[k].args, newargs...)
} else {
statement.inColumns[k] = &inParam{column, newargs}
}
return statement
}
func (statement *Statement) genInSql() (string, []interface{}) {
if len(statement.inColumns) == 0 {
return "", []interface{}{}
}
inStrs := make([]string, len(statement.inColumns), len(statement.inColumns))
args := make([]interface{}, 0, len(statement.inColumns))
var buf bytes.Buffer
var i int
for _, params := range statement.inColumns {
buf.Reset()
fmt.Fprintf(&buf, "(%v IN (%v))",
statement.Engine.quoteColumn(params.colName),
strings.Join(makeArray("?", len(params.args)), ","))
inStrs[i] = buf.String()
i++
args = append(args, params.args...)
}
if len(statement.inColumns) == 1 {
return inStrs[0], args
}
return fmt.Sprintf("(%v)", strings.Join(inStrs, " "+statement.Engine.dialect.AndStr()+" ")), args
}
func (statement *Statement) attachInSql() {
inSql, inArgs := statement.genInSql()
if len(inSql) > 0 {
if len(statement.ConditionStr) > 0 {
statement.ConditionStr += " " + statement.Engine.dialect.AndStr() + " "
}
statement.ConditionStr += inSql
statement.inParams = inArgs
}
}
func (statement *Statement) col2NewColsWithQuote(columns ...string) []string { func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
newColumns := make([]string, 0) newColumns := make([]string, 0)
for _, col := range columns { for _, col := range columns {
@ -1128,18 +1064,38 @@ func (s *Statement) genDelIndexSQL() []string {
return sqls return sqls
} }
func (statement *Statement) genGetSql(bean interface{}) (string, []interface{}) { func (s *Statement) genAddColumnStr(col *core.Column) (string, []interface{}) {
statement.setRefValue(rValue(bean)) quote := s.Engine.Quote
sql := fmt.Sprintf("ALTER TABLE %v ADD %v;", quote(s.TableName()),
col.String(s.Engine.dialect))
return sql, []interface{}{}
}
func (statement *Statement) buildConds(table *core.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) (builder.Cond, error) {
return buildConds(statement.Engine, table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols,
statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName)
}
func (statement *Statement) genConds(bean interface{}) (string, []interface{}, error) {
var table = statement.RefTable var table = statement.RefTable
var addedTableName = (len(statement.JoinStr) > 0) var addedTableName = (len(statement.JoinStr) > 0)
var autoCond builder.Cond
if !statement.noAutoCondition { if !statement.noAutoCondition {
colNames, args := statement.buildConditions(table, bean, true, true, false, true, addedTableName) var err error
autoCond, err = statement.buildConds(table, bean, true, true, false, true, addedTableName)
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ") if err != nil {
statement.BeanArgs = args return "", nil, err
} }
}
statement.processIdParam()
return builder.ToSQL(statement.cond.And(autoCond))
}
func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{}) {
statement.setRefValue(rValue(bean))
var columnStr = statement.ColumnStr var columnStr = statement.ColumnStr
if len(statement.selectStr) > 0 { if len(statement.selectStr) > 0 {
@ -1165,67 +1121,33 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
} }
} }
statement.attachInSql() // !admpub! fix bug:Iterate func missing "... IN (...)" condSQL, condArgs, _ := statement.genConds(bean)
return statement.genSelectSQL(columnStr), append(append(append(statement.joinArgs, statement.Params...),
statement.BeanArgs...), statement.inParams...) return statement.genSelectSQL(columnStr, condSQL), append(statement.joinArgs, condArgs...)
} }
func (s *Statement) genAddColumnStr(col *core.Column) (string, []interface{}) { func (statement *Statement) genCountSQL(bean interface{}) (string, []interface{}) {
quote := s.Engine.Quote
sql := fmt.Sprintf("ALTER TABLE %v ADD %v;", quote(s.TableName()),
col.String(s.Engine.dialect))
return sql, []interface{}{}
}
func (statement *Statement) buildConditions(table *core.Table, bean interface{}, includeVersion bool, includeUpdated bool, includeNil bool, includeAutoIncr bool, addedTableName bool) ([]string, []interface{}) {
return buildConditions(statement.Engine, table, bean, includeVersion, includeUpdated, includeNil, includeAutoIncr, statement.allUseBool, statement.useAllCols,
statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName)
}
func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}) {
statement.setRefValue(rValue(bean)) statement.setRefValue(rValue(bean))
var addedTableName = (len(statement.JoinStr) > 0) condSQL, condArgs, _ := statement.genConds(bean)
if !statement.noAutoCondition { return statement.genSelectSQL("count(*)", condSQL), append(statement.joinArgs, condArgs...)
colNames, args := statement.buildConditions(statement.RefTable, bean, true, true, false, true, addedTableName)
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
statement.BeanArgs = args
} }
// count(index fieldname) > count(0) > count(*) func (statement *Statement) genSumSQL(bean interface{}, columns ...string) (string, []interface{}) {
var id = "*"
if statement.Engine.Dialect().DBType() == "ql" {
id = ""
}
statement.attachInSql()
return statement.genSelectSQL(fmt.Sprintf("count(%v)", id)), append(append(append(statement.joinArgs, statement.Params...),
statement.BeanArgs...), statement.inParams...)
}
func (statement *Statement) genSumSql(bean interface{}, columns ...string) (string, []interface{}) {
statement.setRefValue(rValue(bean)) statement.setRefValue(rValue(bean))
var addedTableName = (len(statement.JoinStr) > 0)
if !statement.noAutoCondition {
colNames, args := statement.buildConditions(statement.RefTable, bean, true, true, false, true, addedTableName)
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
statement.BeanArgs = args
}
statement.attachInSql()
var sumStrs = make([]string, 0, len(columns)) var sumStrs = make([]string, 0, len(columns))
for _, colName := range columns { for _, colName := range columns {
sumStrs = append(sumStrs, fmt.Sprintf("COALESCE(sum(%s),0)", colName)) sumStrs = append(sumStrs, fmt.Sprintf("COALESCE(sum(%s),0)", colName))
} }
return statement.genSelectSQL(strings.Join(sumStrs, ", ")), append(append(append(statement.joinArgs, statement.Params...),
statement.BeanArgs...), statement.inParams...) condSQL, condArgs, _ := statement.genConds(bean)
return statement.genSelectSQL(strings.Join(sumStrs, ", "), condSQL), append(statement.joinArgs, condArgs...)
} }
func (statement *Statement) genSelectSQL(columnStr string) (a string) { func (statement *Statement) genSelectSQL(columnStr, condSQL string) (a string) {
var distinct string var distinct string
if statement.IsDistinct { if statement.IsDistinct {
distinct = "DISTINCT " distinct = "DISTINCT "
@ -1239,17 +1161,8 @@ func (statement *Statement) genSelectSQL(columnStr string) (a string) {
statement.processIdParam() statement.processIdParam()
var buf bytes.Buffer var buf bytes.Buffer
if len(statement.WhereStr) > 0 { if len(condSQL) > 0 {
if len(statement.ConditionStr) > 0 { fmt.Fprintf(&buf, " WHERE %v", condSQL)
fmt.Fprintf(&buf, " WHERE (%v)", statement.WhereStr)
} else {
fmt.Fprintf(&buf, " WHERE %v", statement.WhereStr)
}
if statement.ConditionStr != "" {
fmt.Fprintf(&buf, " %s (%v)", dialect.AndStr(), statement.ConditionStr)
}
} else if len(statement.ConditionStr) > 0 {
fmt.Fprintf(&buf, " WHERE %v", statement.ConditionStr)
} }
var whereStr = buf.String() var whereStr = buf.String()
@ -1333,27 +1246,21 @@ func (statement *Statement) genSelectSQL(columnStr string) (a string) {
} }
func (statement *Statement) processIdParam() { func (statement *Statement) processIdParam() {
if statement.IdParam != nil { if statement.IdParam == nil {
if statement.Engine.dialect.DBType() != "ql" { return
}
for i, col := range statement.RefTable.PKColumns() { for i, col := range statement.RefTable.PKColumns() {
var colName = statement.colName(col, statement.TableName()) var colName = statement.colName(col, statement.TableName())
if i < len(*(statement.IdParam)) { if i < len(*(statement.IdParam)) {
statement.And(fmt.Sprintf("%v %s ?", colName, statement.cond = statement.cond.And(builder.Eq{colName: (*(statement.IdParam))[i]})
statement.Engine.dialect.EqStr()), (*(statement.IdParam))[i])
} else { } else {
statement.And(fmt.Sprintf("%v %s ?", colName, statement.cond = statement.cond.And(builder.Eq{colName: ""})
statement.Engine.dialect.EqStr()), "")
}
}
} else {
if len(*(statement.IdParam)) <= 1 {
statement.And("id() == ?", (*(statement.IdParam))[0])
}
} }
} }
} }
func (statement *Statement) JoinColumns(cols []*core.Column, includeTableName bool) string { func (statement *Statement) joinColumns(cols []*core.Column, includeTableName bool) string {
var colnames = make([]string, len(cols)) var colnames = make([]string, len(cols))
for i, col := range cols { for i, col := range cols {
if includeTableName { if includeTableName {
@ -1366,21 +1273,19 @@ func (statement *Statement) JoinColumns(cols []*core.Column, includeTableName bo
return strings.Join(colnames, ", ") return strings.Join(colnames, ", ")
} }
func (statement *Statement) convertIdSql(sqlStr string) string { func (statement *Statement) convertIDSQL(sqlStr string) string {
if statement.RefTable != nil { if statement.RefTable != nil {
cols := statement.RefTable.PKColumns() cols := statement.RefTable.PKColumns()
if len(cols) == 0 { if len(cols) == 0 {
return "" return ""
} }
colstrs := statement.JoinColumns(cols, false) colstrs := statement.joinColumns(cols, false)
sqls := splitNNoCase(sqlStr, " from ", 2) sqls := splitNNoCase(sqlStr, " from ", 2)
if len(sqls) != 2 { if len(sqls) != 2 {
return "" return ""
} }
if statement.Engine.dialect.DBType() == "ql" {
return fmt.Sprintf("SELECT id() FROM %v", sqls[1])
}
return fmt.Sprintf("SELECT %s FROM %v", colstrs, sqls[1]) return fmt.Sprintf("SELECT %s FROM %v", colstrs, sqls[1])
} }
return "" return ""
@ -1391,7 +1296,7 @@ func (statement *Statement) convertUpdateSQL(sqlStr string) (string, string) {
return "", "" return "", ""
} }
colstrs := statement.JoinColumns(statement.RefTable.PKColumns(), true) colstrs := statement.joinColumns(statement.RefTable.PKColumns(), true)
sqls := splitNNoCase(sqlStr, "where", 2) sqls := splitNNoCase(sqlStr, "where", 2)
if len(sqls) != 2 { if len(sqls) != 2 {
if len(sqls) == 1 { if len(sqls) == 1 {

View File

@ -17,7 +17,7 @@ import (
const ( const (
// Version show the xorm's version // Version show the xorm's version
Version string = "0.5.6.0921" Version string = "0.6.0.0921"
) )
func regDrvsNDialects() bool { func regDrvsNDialects() bool {