add Exist functions (#640)
This commit is contained in:
parent
78795d8f13
commit
774f83c1bc
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://goreportcard.com/report/github.com/go-xorm/xorm)
|
||||||
[](https://discord.gg/HuR2CF3)
|
[](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
|
# Features
|
||||||
|
|
||||||
* Struct <-> Table Mapping Support
|
* Struct <-> Table Mapping Support
|
||||||
|
@ -52,6 +48,14 @@ Drivers for Go's sql package which currently support database/sql includes:
|
||||||
|
|
||||||
# Changelog
|
# 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**
|
* **v0.6.2**
|
||||||
* refactor tag parse methods
|
* refactor tag parse methods
|
||||||
* add Scan features to Get
|
* add Scan features to Get
|
||||||
|
@ -68,18 +72,6 @@ methods can use `builder.Cond` as parameter
|
||||||
* logging interface changed
|
* logging interface changed
|
||||||
* some bugs fixed
|
* 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)
|
[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16)
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
@ -168,6 +160,25 @@ has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
||||||
// SELECT col1, col2, col3 FROM user WHERE id = ?
|
// 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
|
* Query multiple records from database, also you can use join and extends
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
|
@ -260,6 +271,12 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
|
||||||
|
|
||||||
# Cases
|
# 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)
|
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||||
|
|
||||||
* [Wego](http://github.com/go-tango/wego)
|
* [Wego](http://github.com/go-tango/wego)
|
||||||
|
@ -268,8 +285,6 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
|
||||||
|
|
||||||
* [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)
|
* [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)
|
||||||
|
|
||||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
|
||||||
|
|
||||||
* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel)
|
* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel)
|
||||||
|
|
||||||
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)
|
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)
|
||||||
|
|
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://goreportcard.com/report/github.com/go-xorm/xorm)
|
||||||
[](https://discord.gg/HuR2CF3)
|
[](https://discord.gg/HuR2CF3)
|
||||||
|
|
||||||
# 注意
|
|
||||||
|
|
||||||
最新的版本有不兼容的更新,您必须使用 `engine.ShowSQL()` 和 `engine.Logger().SetLevel()` 来替代 `engine.ShowSQL = `, `engine.ShowInfo = ` 等等。
|
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
||||||
* 支持Struct和数据库表之间的灵活映射,并支持自动同步
|
* 支持Struct和数据库表之间的灵活映射,并支持自动同步
|
||||||
|
@ -56,6 +52,15 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
* **v0.6.3**
|
||||||
|
* 合并单元测试到主工程
|
||||||
|
* 新增`Exist`方法
|
||||||
|
* 新增`SumInt`方法
|
||||||
|
* Mysql新增读取和创建字段注释支持
|
||||||
|
* 新增`SetConnMaxLifetime`方法
|
||||||
|
* 修正了时间相关的Bug
|
||||||
|
* 修复了一些其它Bug
|
||||||
|
|
||||||
* **v0.6.2**
|
* **v0.6.2**
|
||||||
* 重构Tag解析方式
|
* 重构Tag解析方式
|
||||||
* Get方法新增类似Scan的特性
|
* Get方法新增类似Scan的特性
|
||||||
|
@ -72,18 +77,6 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||||
* logging接口进行不兼容改变
|
* logging接口进行不兼容改变
|
||||||
* Bug修正
|
* 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)
|
[更多更新日志...](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 = ?
|
// 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来组合使用
|
* 查询多条记录,当然可以使用Join和extends来组合使用
|
||||||
|
|
||||||
```Go
|
```Go
|
||||||
|
@ -263,6 +275,12 @@ 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)
|
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||||
|
|
||||||
* [Wego](http://github.com/go-tango/wego)
|
* [Wego](http://github.com/go-tango/wego)
|
||||||
|
@ -271,8 +289,6 @@ err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))
|
||||||
|
|
||||||
* [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)
|
* [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)
|
||||||
|
|
||||||
* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)
|
|
||||||
|
|
||||||
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)
|
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)
|
||||||
|
|
||||||
* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild)
|
* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild)
|
||||||
|
|
|
@ -1426,6 +1426,13 @@ func (engine *Engine) Get(bean interface{}) (bool, error) {
|
||||||
return session.Get(bean)
|
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
|
// Find retrieve records from table, condiBeans's non-empty fields
|
||||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||||
// map[int64]*Struct
|
// map[int64]*Struct
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in New Issue