Merge branch 'master' of https://github.com/go-xorm/xorm into nil_ptr_is_nullable
This commit is contained in:
commit
925202e742
51
README.md
51
README.md
|
@ -6,10 +6,6 @@ Xorm is a simple and powerful ORM for Go.
|
|||
[](https://goreportcard.com/report/github.com/go-xorm/xorm)
|
||||
[](https://discord.gg/HuR2CF3)
|
||||
|
||||
# Notice
|
||||
|
||||
The last master version is not backwards compatible. You should use `engine.ShowSQL()` and `engine.Logger().SetLevel()` instead of `engine.ShowSQL = `, `engine.ShowInfo = ` and so on.
|
||||
|
||||
# Features
|
||||
|
||||
* Struct <-> Table Mapping Support
|
||||
|
@ -52,6 +48,14 @@ Drivers for Go's sql package which currently support database/sql includes:
|
|||
|
||||
# Changelog
|
||||
|
||||
* **v0.6.3**
|
||||
* merge tests to main project
|
||||
* add `Exist` function
|
||||
* add `SumInt` function
|
||||
* Mysql now support read and create column comment.
|
||||
* fix time related bugs.
|
||||
* fix some other bugs.
|
||||
|
||||
* **v0.6.2**
|
||||
* refactor tag parse methods
|
||||
* add Scan features to Get
|
||||
|
@ -68,18 +72,6 @@ methods can use `builder.Cond` as parameter
|
|||
* logging interface changed
|
||||
* some bugs fixed
|
||||
|
||||
* **v0.4.5**
|
||||
* many bugs fixed
|
||||
* extends support unlimited deepth
|
||||
* Delete Limit support
|
||||
|
||||
* **v0.4.4**
|
||||
* ql database expriment support
|
||||
* tidb database expriment support
|
||||
* sql.NullString and etc. field support
|
||||
* select ForUpdate support
|
||||
* many bugs fixed
|
||||
|
||||
[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16)
|
||||
|
||||
# Installation
|
||||
|
@ -168,6 +160,25 @@ has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
|||
// SELECT col1, col2, col3 FROM user WHERE id = ?
|
||||
```
|
||||
|
||||
* Check if one record exist on table
|
||||
|
||||
```Go
|
||||
has, err := testEngine.Exist(new(RecordExist))
|
||||
// SELECT * FROM record_exist LIMIT 1
|
||||
has, err = testEngine.Exist(&RecordExist{
|
||||
Name: "test1",
|
||||
})
|
||||
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
|
||||
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
|
||||
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
|
||||
has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
|
||||
// select * from record_exist where name = ?
|
||||
has, err = testEngine.Table("record_exist").Exist()
|
||||
// SELECT * FROM record_exist LIMIT 1
|
||||
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
|
||||
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
|
||||
```
|
||||
|
||||
* Query multiple records from database, also you can use join and extends
|
||||
|
||||
```Go
|
||||
|
@ -260,13 +271,19 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
|
|||
|
||||
# Cases
|
||||
|
||||
* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
|
||||
* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana)
|
||||
|
||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [Docker.cn](https://docker.cn/)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter)
|
||||
|
||||
* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel)
|
||||
|
||||
|
|
52
README_CN.md
52
README_CN.md
|
@ -8,10 +8,6 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
|||
[](https://goreportcard.com/report/github.com/go-xorm/xorm)
|
||||
[](https://discord.gg/HuR2CF3)
|
||||
|
||||
# 注意
|
||||
|
||||
最新的版本有不兼容的更新,您必须使用 `engine.ShowSQL()` 和 `engine.Logger().SetLevel()` 来替代 `engine.ShowSQL = `, `engine.ShowInfo = ` 等等。
|
||||
|
||||
## 特性
|
||||
|
||||
* 支持Struct和数据库表之间的灵活映射,并支持自动同步
|
||||
|
@ -56,6 +52,15 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
|||
|
||||
## 更新日志
|
||||
|
||||
* **v0.6.3**
|
||||
* 合并单元测试到主工程
|
||||
* 新增`Exist`方法
|
||||
* 新增`SumInt`方法
|
||||
* Mysql新增读取和创建字段注释支持
|
||||
* 新增`SetConnMaxLifetime`方法
|
||||
* 修正了时间相关的Bug
|
||||
* 修复了一些其它Bug
|
||||
|
||||
* **v0.6.2**
|
||||
* 重构Tag解析方式
|
||||
* Get方法新增类似Scan的特性
|
||||
|
@ -72,18 +77,6 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
|||
* logging接口进行不兼容改变
|
||||
* Bug修正
|
||||
|
||||
* **v0.4.5**
|
||||
* bug修正
|
||||
* extends 支持无限级
|
||||
* Delete Limit 支持
|
||||
|
||||
* **v0.4.4**
|
||||
* Tidb 数据库支持
|
||||
* QL 试验性支持
|
||||
* sql.NullString支持
|
||||
* ForUpdate 支持
|
||||
* bug修正
|
||||
|
||||
[更多更新日志...](https://github.com/go-xorm/manual-zh-CN/tree/master/chapter-16)
|
||||
|
||||
## 安装
|
||||
|
@ -172,6 +165,25 @@ has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
|||
// SELECT col1, col2, col3 FROM user WHERE id = ?
|
||||
```
|
||||
|
||||
* 检测记录是否存在
|
||||
|
||||
```Go
|
||||
has, err := testEngine.Exist(new(RecordExist))
|
||||
// SELECT * FROM record_exist LIMIT 1
|
||||
has, err = testEngine.Exist(&RecordExist{
|
||||
Name: "test1",
|
||||
})
|
||||
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
|
||||
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
|
||||
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
|
||||
has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
|
||||
// select * from record_exist where name = ?
|
||||
has, err = testEngine.Table("record_exist").Exist()
|
||||
// SELECT * FROM record_exist LIMIT 1
|
||||
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
|
||||
// SELECT * FROM record_exist WHERE name = ? LIMIT 1
|
||||
```
|
||||
|
||||
* 查询多条记录,当然可以使用Join和extends来组合使用
|
||||
|
||||
```Go
|
||||
|
@ -263,13 +275,19 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
|
|||
|
||||
# 案例
|
||||
|
||||
* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
|
||||
* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana)
|
||||
|
||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||
|
||||
* [Wego](http://github.com/go-tango/wego)
|
||||
|
||||
* [Docker.cn](https://docker.cn/)
|
||||
|
||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
||||
* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter)
|
||||
|
||||
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ database:
|
|||
test:
|
||||
override:
|
||||
# './...' is a relative pattern which means all subdirectories
|
||||
- go test -v -race -db="sqlite3::mysql::postgres" -conn_str="./test.db::root:@/xorm_test::dbname=xorm_test sslmode=disable" -coverprofile=coverage.txt -covermode=atomic
|
||||
- go test -v -race -db="sqlite3::mysql::mymysql::postgres" -conn_str="./test.db::root:@/xorm_test::xorm_test/root/::dbname=xorm_test sslmode=disable" -coverprofile=coverage.txt -covermode=atomic
|
||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./sqlite3.sh
|
||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./mysql.sh
|
||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh
|
||||
|
|
|
@ -267,7 +267,7 @@ func (engine *Engine) Ping() error {
|
|||
func (engine *Engine) logSQL(sqlStr string, sqlArgs ...interface{}) {
|
||||
if engine.showSQL && !engine.showExecTime {
|
||||
if len(sqlArgs) > 0 {
|
||||
engine.logger.Infof("[SQL] %v %v", sqlStr, sqlArgs)
|
||||
engine.logger.Infof("[SQL] %v %#v", sqlStr, sqlArgs)
|
||||
} else {
|
||||
engine.logger.Infof("[SQL] %v", sqlStr)
|
||||
}
|
||||
|
@ -1426,6 +1426,13 @@ func (engine *Engine) Get(bean interface{}) (bool, error) {
|
|||
return session.Get(bean)
|
||||
}
|
||||
|
||||
// Exist returns true if the record exist otherwise return false
|
||||
func (engine *Engine) Exist(bean ...interface{}) (bool, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Exist(bean...)
|
||||
}
|
||||
|
||||
// Find retrieve records from table, condiBeans's non-empty fields
|
||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||
// map[int64]*Struct
|
||||
|
|
|
@ -93,11 +93,15 @@ func (session *Session) Close() {
|
|||
}
|
||||
session.Tx = nil
|
||||
session.stmtCache = nil
|
||||
session.Init()
|
||||
session.db = nil
|
||||
}
|
||||
}
|
||||
|
||||
// IsClosed returns if session is closed
|
||||
func (session *Session) IsClosed() bool {
|
||||
return session.db == nil
|
||||
}
|
||||
|
||||
func (session *Session) resetStatement() {
|
||||
if session.AutoResetStatement {
|
||||
session.Statement.Init()
|
||||
|
|
|
@ -35,3 +35,35 @@ func TestSetExpr(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
}
|
||||
|
||||
func TestCols(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type ColsTable struct {
|
||||
Id int64
|
||||
Col1 string
|
||||
Col2 string
|
||||
}
|
||||
|
||||
assertSync(t, new(ColsTable))
|
||||
|
||||
_, err := testEngine.Insert(&ColsTable{
|
||||
Col1: "1",
|
||||
Col2: "2",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
sess := testEngine.ID(1)
|
||||
_, err = sess.Cols("col1").Cols("col2").Update(&ColsTable{
|
||||
Col1: "",
|
||||
Col2: "",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
var tb ColsTable
|
||||
has, err := testEngine.ID(1).Get(&tb)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, "", tb.Col1)
|
||||
assert.EqualValues(t, "", tb.Col2)
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func (session *Session) NotIn(column string, args ...interface{}) *Session {
|
|||
return session
|
||||
}
|
||||
|
||||
// Conds returns session query conditions
|
||||
// Conds returns session query conditions except auto bean conditions
|
||||
func (session *Session) Conds() builder.Cond {
|
||||
return session.Statement.cond
|
||||
}
|
||||
|
|
|
@ -260,3 +260,35 @@ func TestIn(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindAndCount(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type FindAndCount struct {
|
||||
Id int64
|
||||
Name string
|
||||
}
|
||||
|
||||
assert.NoError(t, testEngine.Sync2(new(FindAndCount)))
|
||||
|
||||
_, err := testEngine.Insert([]FindAndCount{
|
||||
{
|
||||
Name: "test1",
|
||||
},
|
||||
{
|
||||
Name: "test2",
|
||||
},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
var results []FindAndCount
|
||||
sess := testEngine.Where("name = ?", "test1")
|
||||
conds := sess.Conds()
|
||||
err = sess.Find(&results)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, len(results))
|
||||
|
||||
total, err := testEngine.Where(conds).Count(new(FindAndCount))
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, total)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ func TestDelete(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
cnt, err = testEngine.Delete(&UserinfoDelete{Uid: 1})
|
||||
cnt, err = testEngine.Delete(&UserinfoDelete{Uid: user.Uid})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
|
@ -35,6 +35,20 @@ func TestDelete(t *testing.T) {
|
|||
has, err := testEngine.Id(1).Get(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
|
||||
cnt, err = testEngine.Insert(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
cnt, err = testEngine.Where("id=?", user.Uid).Delete(&UserinfoDelete{})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
user.Uid = 0
|
||||
user.IsMan = true
|
||||
has, err = testEngine.Id(2).Get(&user)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
}
|
||||
|
||||
func TestDeleted(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
)
|
||||
|
||||
// Exist returns true if the record exist otherwise return false
|
||||
func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
||||
defer session.resetStatement()
|
||||
if session.IsAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
var sqlStr string
|
||||
var args []interface{}
|
||||
var err error
|
||||
|
||||
if session.Statement.RawSQL == "" {
|
||||
if len(bean) == 0 {
|
||||
tableName := session.Statement.TableName()
|
||||
if len(tableName) <= 0 {
|
||||
return false, ErrTableNotFound
|
||||
}
|
||||
|
||||
if session.Statement.cond.IsValid() {
|
||||
condSQL, condArgs, err := builder.ToSQL(session.Statement.cond)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
|
||||
args = condArgs
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
|
||||
args = []interface{}{}
|
||||
}
|
||||
} else {
|
||||
beanValue := reflect.ValueOf(bean[0])
|
||||
if beanValue.Kind() != reflect.Ptr {
|
||||
return false, errors.New("needs a pointer")
|
||||
}
|
||||
|
||||
if beanValue.Elem().Kind() == reflect.Struct {
|
||||
if err := session.Statement.setRefValue(beanValue.Elem()); err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(session.Statement.TableName()) <= 0 {
|
||||
return false, ErrTableNotFound
|
||||
}
|
||||
session.Statement.Limit(1)
|
||||
sqlStr, args, err = session.Statement.genGetSQL(bean[0])
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sqlStr = session.Statement.RawSQL
|
||||
args = session.Statement.RawParams
|
||||
}
|
||||
|
||||
session.queryPreprocess(&sqlStr, args...)
|
||||
|
||||
var rawRows *core.Rows
|
||||
if session.IsAutoCommit {
|
||||
_, rawRows, err = session.innerQuery(sqlStr, args...)
|
||||
} else {
|
||||
rawRows, err = session.Tx.Query(sqlStr, args...)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer rawRows.Close()
|
||||
|
||||
return rawRows.Next(), nil
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestExistStruct(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type RecordExist struct {
|
||||
Id int64
|
||||
Name string
|
||||
}
|
||||
|
||||
assertSync(t, new(RecordExist))
|
||||
|
||||
has, err := testEngine.Exist(new(RecordExist))
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
|
||||
cnt, err := testEngine.Insert(&RecordExist{
|
||||
Name: "test1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
has, err = testEngine.Exist(new(RecordExist))
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
|
||||
has, err = testEngine.Exist(&RecordExist{
|
||||
Name: "test1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
|
||||
has, err = testEngine.Exist(&RecordExist{
|
||||
Name: "test2",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
|
||||
has, err = testEngine.Where("name = ?", "test1").Exist(&RecordExist{})
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
|
||||
has, err = testEngine.Where("name = ?", "test2").Exist(&RecordExist{})
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
|
||||
has, err = testEngine.SQL("select * from record_exist where name = ?", "test1").Exist()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
|
||||
has, err = testEngine.SQL("select * from record_exist where name = ?", "test2").Exist()
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
|
||||
has, err = testEngine.Table("record_exist").Exist()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
|
||||
has, err = testEngine.Table("record_exist").Where("name = ?", "test1").Exist()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
|
||||
has, err = testEngine.Table("record_exist").Where("name = ?", "test2").Exist()
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, has)
|
||||
}
|
|
@ -119,7 +119,8 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
|||
}
|
||||
}
|
||||
|
||||
condSQL, condArgs, err := builder.ToSQL(session.Statement.cond.And(autoCond))
|
||||
session.Statement.cond = session.Statement.cond.And(autoCond)
|
||||
condSQL, condArgs, err := builder.ToSQL(session.Statement.cond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -71,15 +71,18 @@ func TestGetVar(t *testing.T) {
|
|||
assert.Equal(t, "28", valuesString["age"])
|
||||
assert.Equal(t, "1.5", valuesString["money"])
|
||||
|
||||
var valuesInter = make(map[string]interface{})
|
||||
has, err = testEngine.Table("get_var").Where("id = ?", 1).Select("*").Get(&valuesInter)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.Equal(t, 5, len(valuesInter))
|
||||
assert.EqualValues(t, 1, valuesInter["id"])
|
||||
assert.Equal(t, "hi", fmt.Sprintf("%s", valuesInter["msg"]))
|
||||
assert.EqualValues(t, 28, valuesInter["age"])
|
||||
assert.Equal(t, "1.5", fmt.Sprintf("%v", valuesInter["money"]))
|
||||
// for mymysql driver, interface{} will be []byte, so ignore it currently
|
||||
if testEngine.dialect.DriverName() != "mymysql" {
|
||||
var valuesInter = make(map[string]interface{})
|
||||
has, err = testEngine.Table("get_var").Where("id = ?", 1).Select("*").Get(&valuesInter)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.Equal(t, 5, len(valuesInter))
|
||||
assert.EqualValues(t, 1, valuesInter["id"])
|
||||
assert.Equal(t, "hi", fmt.Sprintf("%s", valuesInter["msg"]))
|
||||
assert.EqualValues(t, 28, valuesInter["age"])
|
||||
assert.Equal(t, "1.5", fmt.Sprintf("%v", valuesInter["money"]))
|
||||
}
|
||||
|
||||
var valuesSliceString = make([]string, 5)
|
||||
has, err = testEngine.Table("get_var").Get(&valuesSliceString)
|
||||
|
|
|
@ -18,10 +18,7 @@ func (session *Session) Count(bean ...interface{}) (int64, error) {
|
|||
var args []interface{}
|
||||
var err error
|
||||
if session.Statement.RawSQL == "" {
|
||||
if len(bean) == 0 {
|
||||
return 0, ErrTableNotFound
|
||||
}
|
||||
sqlStr, args, err = session.Statement.genCountSQL(bean[0])
|
||||
sqlStr, args, err = session.Statement.genCountSQL(bean...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
|
@ -127,6 +127,14 @@ func TestCount(t *testing.T) {
|
|||
total, err = testEngine.Where(cond).Count(new(UserinfoCount))
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, total)
|
||||
|
||||
total, err = testEngine.Where(cond).Table("userinfo_count").Count()
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, total)
|
||||
|
||||
total, err = testEngine.Table("userinfo_count").Count()
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, total)
|
||||
}
|
||||
|
||||
func TestSQLCount(t *testing.T) {
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2017 The Xorm Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xorm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
sess1 := testEngine.NewSession()
|
||||
sess1.Close()
|
||||
assert.True(t, sess1.IsClosed())
|
||||
|
||||
sess2 := testEngine.Where("a = ?", 1)
|
||||
sess2.Close()
|
||||
assert.True(t, sess2.IsClosed())
|
||||
}
|
|
@ -330,6 +330,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
}
|
||||
}
|
||||
|
||||
if len(colNames) <= 0 {
|
||||
return 0, errors.New("No content found to be updated")
|
||||
}
|
||||
|
||||
sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v",
|
||||
top,
|
||||
session.Engine.Quote(session.Statement.TableName()),
|
||||
|
|
|
@ -1093,3 +1093,23 @@ func TestBool(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoUpdate(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type NoUpdate struct {
|
||||
Id int64
|
||||
Content string
|
||||
}
|
||||
|
||||
assertSync(t, new(NoUpdate))
|
||||
|
||||
_, err := testEngine.Insert(&NoUpdate{
|
||||
Content: "test",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = testEngine.Id(1).Update(&NoUpdate{})
|
||||
assert.Error(t, err)
|
||||
assert.EqualValues(t, "No content found to be updated", err.Error())
|
||||
}
|
||||
|
|
53
statement.go
53
statement.go
|
@ -592,6 +592,22 @@ func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
|||
return newColumns
|
||||
}
|
||||
|
||||
func (statement *Statement) colmap2NewColsWithQuote() []string {
|
||||
newColumns := make([]string, 0, len(statement.columnMap))
|
||||
for col := range statement.columnMap {
|
||||
fields := strings.Split(strings.TrimSpace(col), ".")
|
||||
if len(fields) == 1 {
|
||||
newColumns = append(newColumns, statement.Engine.quote(fields[0]))
|
||||
} else if len(fields) == 2 {
|
||||
newColumns = append(newColumns, statement.Engine.quote(fields[0])+"."+
|
||||
statement.Engine.quote(fields[1]))
|
||||
} else {
|
||||
panic(errors.New("unwanted colnames"))
|
||||
}
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
|
||||
// Distinct generates "DISTINCT col1, col2 " statement
|
||||
func (statement *Statement) Distinct(columns ...string) *Statement {
|
||||
statement.IsDistinct = true
|
||||
|
@ -618,7 +634,7 @@ func (statement *Statement) Cols(columns ...string) *Statement {
|
|||
statement.columnMap[strings.ToLower(nc)] = true
|
||||
}
|
||||
|
||||
newColumns := statement.col2NewColsWithQuote(columns...)
|
||||
newColumns := statement.colmap2NewColsWithQuote()
|
||||
statement.ColumnStr = strings.Join(newColumns, ", ")
|
||||
statement.ColumnStr = strings.Replace(statement.ColumnStr, statement.Engine.quote("*"), "*", -1)
|
||||
return statement
|
||||
|
@ -890,17 +906,24 @@ func (statement *Statement) buildConds(table *core.Table, bean interface{}, incl
|
|||
statement.unscoped, statement.mustColumnMap, statement.TableName(), statement.TableAlias, addedTableName)
|
||||
}
|
||||
|
||||
func (statement *Statement) genConds(bean interface{}) (string, []interface{}, error) {
|
||||
func (statement *Statement) mergeConds(bean interface{}) error {
|
||||
if !statement.noAutoCondition {
|
||||
var addedTableName = (len(statement.JoinStr) > 0)
|
||||
autoCond, err := statement.buildConds(statement.RefTable, bean, true, true, false, true, addedTableName)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return err
|
||||
}
|
||||
statement.cond = statement.cond.And(autoCond)
|
||||
}
|
||||
|
||||
if err := statement.processIDParam(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (statement *Statement) genConds(bean interface{}) (string, []interface{}, error) {
|
||||
if err := statement.mergeConds(bean); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
|
@ -940,14 +963,12 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
|||
columnStr = "*"
|
||||
}
|
||||
|
||||
var condSQL string
|
||||
var condArgs []interface{}
|
||||
var err error
|
||||
if isStruct {
|
||||
condSQL, condArgs, err = statement.genConds(bean)
|
||||
} else {
|
||||
condSQL, condArgs, err = builder.ToSQL(statement.cond)
|
||||
if err := statement.mergeConds(bean); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
condSQL, condArgs, err := builder.ToSQL(statement.cond)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
@ -960,10 +981,16 @@ func (statement *Statement) genGetSQL(bean interface{}) (string, []interface{},
|
|||
return sqlStr, append(statement.joinArgs, condArgs...), nil
|
||||
}
|
||||
|
||||
func (statement *Statement) genCountSQL(bean interface{}) (string, []interface{}, error) {
|
||||
statement.setRefValue(rValue(bean))
|
||||
|
||||
condSQL, condArgs, err := statement.genConds(bean)
|
||||
func (statement *Statement) genCountSQL(beans ...interface{}) (string, []interface{}, error) {
|
||||
var condSQL string
|
||||
var condArgs []interface{}
|
||||
var err error
|
||||
if len(beans) > 0 {
|
||||
statement.setRefValue(rValue(beans[0]))
|
||||
condSQL, condArgs, err = statement.genConds(beans[0])
|
||||
} else {
|
||||
condSQL, condArgs, err = builder.ToSQL(statement.cond)
|
||||
}
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
go test -db=mymysql -conn_str="xorm_test/root/"
|
2
xorm.go
2
xorm.go
|
@ -17,7 +17,7 @@ import (
|
|||
|
||||
const (
|
||||
// Version show the xorm's version
|
||||
Version string = "0.6.2.0605"
|
||||
Version string = "0.6.3.0713"
|
||||
)
|
||||
|
||||
func regDrvsNDialects() bool {
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/go-xorm/core"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
_ "github.com/ziutek/mymysql/godrv"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
Loading…
Reference in New Issue