add Exist functions (#640)

This commit is contained in:
Lunny Xiao 2017-07-14 09:20:13 +08:00 committed by GitHub
parent 78795d8f13
commit 774f83c1bc
6 changed files with 238 additions and 37 deletions

View File

@ -6,10 +6,6 @@ Xorm is a simple and powerful ORM for Go.
[![](https://goreportcard.com/badge/github.com/go-xorm/xorm)](https://goreportcard.com/report/github.com/go-xorm/xorm)
[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](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,6 +271,12 @@ 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)
@ -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)
* [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)
* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)

View File

@ -8,10 +8,6 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
[![](https://goreportcard.com/badge/github.com/go-xorm/xorm)](https://goreportcard.com/report/github.com/go-xorm/xorm)
[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](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,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)
* [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)
* [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)
* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild)

View File

@ -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

87
session_exist.go Normal file
View File

@ -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
}

76
session_exist_test.go Normal file
View File

@ -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)
}

View File

@ -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 {