Merge branch 'master' into lunny/test_oracle
This commit is contained in:
commit
98a8c6f851
|
@ -35,8 +35,8 @@ jobs:
|
|||
- checkout
|
||||
|
||||
- run: go get -t -d -v ./...
|
||||
- run: go get -u github.com/go-xorm/core
|
||||
- run: go get -u github.com/go-xorm/builder
|
||||
- run: go get -u xorm.io/core
|
||||
- run: go get -u xorm.io/builder
|
||||
- run: GO111MODULE=off go build -v
|
||||
- run: GO111MODULE=on go build -v
|
||||
|
||||
|
|
|
@ -37,10 +37,9 @@ services:
|
|||
|
||||
matrix:
|
||||
GO_VERSION:
|
||||
- 1.8
|
||||
- 1.9
|
||||
- 1.10
|
||||
- 1.11
|
||||
- 1.12
|
||||
|
||||
pipeline:
|
||||
init_postgres:
|
||||
|
@ -59,8 +58,8 @@ pipeline:
|
|||
image: golang:${GO_VERSION}
|
||||
commands:
|
||||
- go get -t -d -v ./...
|
||||
- go get -u github.com/go-xorm/core
|
||||
- go get -u github.com/go-xorm/builder
|
||||
- go get -u xorm.io/core
|
||||
- go get -u xorm.io/builder
|
||||
- go build -v
|
||||
when:
|
||||
event: [ push, pull_request ]
|
||||
|
|
19
README.md
19
README.md
|
@ -28,7 +28,7 @@ Xorm is a simple and powerful ORM for Go.
|
|||
|
||||
* Optimistic Locking support
|
||||
|
||||
* SQL Builder support via [github.com/go-xorm/builder](https://github.com/go-xorm/builder)
|
||||
* SQL Builder support via [xorm.io/builder](https://xorm.io/builder)
|
||||
|
||||
* Automatical Read/Write seperatelly
|
||||
|
||||
|
@ -151,20 +151,20 @@ has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
|||
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||
|
||||
var name string
|
||||
has, err := engine.Where("id = ?", id).Cols("name").Get(&name)
|
||||
has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name)
|
||||
// SELECT name FROM user WHERE id = ?
|
||||
|
||||
var id int64
|
||||
has, err := engine.Where("name = ?", name).Cols("id").Get(&id)
|
||||
has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id)
|
||||
has, err := engine.SQL("select id from user").Get(&id)
|
||||
// SELECT id FROM user WHERE name = ?
|
||||
|
||||
var valuesMap = make(map[string]string)
|
||||
has, err := engine.Where("id = ?", id).Get(&valuesMap)
|
||||
has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap)
|
||||
// SELECT * FROM user WHERE id = ?
|
||||
|
||||
var valuesSlice = make([]interface{}, len(cols))
|
||||
has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
||||
has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
||||
// SELECT col1, col2, col3 FROM user WHERE id = ?
|
||||
```
|
||||
|
||||
|
@ -284,6 +284,13 @@ counts, err := engine.Count(&user)
|
|||
// SELECT count(*) AS total FROM user
|
||||
```
|
||||
|
||||
* `FindAndCount` combines function `Find` with `Count` which is usually used in query by page
|
||||
|
||||
```Go
|
||||
var users []User
|
||||
counts, err := engine.FindAndCount(&users)
|
||||
```
|
||||
|
||||
* `Sum` sum functions
|
||||
|
||||
```Go
|
||||
|
@ -363,7 +370,7 @@ return session.Commit()
|
|||
* Or you can use `Transaction` to replace above codes.
|
||||
|
||||
```Go
|
||||
res, err := engine.Transaction(func(sess *xorm.Session) (interface{}, error) {
|
||||
res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) {
|
||||
user1 := Userinfo{Username: "xiaoxiao", Departname: "dev", Alias: "lunny", Created: time.Now()}
|
||||
if _, err := session.Insert(&user1); err != nil {
|
||||
return nil, err
|
||||
|
|
10
README_CN.md
10
README_CN.md
|
@ -153,20 +153,20 @@ has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
|||
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||
|
||||
var name string
|
||||
has, err := engine.Where("id = ?", id).Cols("name").Get(&name)
|
||||
has, err := engine.Table(&user).Where("id = ?", id).Cols("name").Get(&name)
|
||||
// SELECT name FROM user WHERE id = ?
|
||||
|
||||
var id int64
|
||||
has, err := engine.Where("name = ?", name).Cols("id").Get(&id)
|
||||
has, err := engine.Table(&user).Where("name = ?", name).Cols("id").Get(&id)
|
||||
has, err := engine.SQL("select id from user").Get(&id)
|
||||
// SELECT id FROM user WHERE name = ?
|
||||
|
||||
var valuesMap = make(map[string]string)
|
||||
has, err := engine.Where("id = ?", id).Get(&valuesMap)
|
||||
has, err := engine.Table(&user).Where("id = ?", id).Get(&valuesMap)
|
||||
// SELECT * FROM user WHERE id = ?
|
||||
|
||||
var valuesSlice = make([]interface{}, len(cols))
|
||||
has, err := engine.Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
||||
has, err := engine.Table(&user).Where("id = ?", id).Cols(cols...).Get(&valuesSlice)
|
||||
// SELECT col1, col2, col3 FROM user WHERE id = ?
|
||||
```
|
||||
|
||||
|
@ -362,7 +362,7 @@ if _, err := session.Exec("delete from userinfo where username = ?", user2.Usern
|
|||
return session.Commit()
|
||||
```
|
||||
|
||||
* 事物的简写方法
|
||||
* 事务的简写方法
|
||||
|
||||
```Go
|
||||
res, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) {
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// LRUCacher implments cache object facilities
|
||||
|
|
|
@ -7,7 +7,7 @@ package xorm
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ package xorm
|
|||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var _ core.CacheStore = NewMemoryStore()
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -286,10 +286,6 @@ func (db *mssql) Quote(name string) string {
|
|||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *mssql) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (db *mssql) SupportEngine() bool {
|
||||
return false
|
||||
}
|
||||
|
@ -507,7 +503,7 @@ func (db *mssql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
|
|||
|
||||
sql = "IF NOT EXISTS (SELECT [name] FROM sys.tables WHERE [name] = '" + tableName + "' ) CREATE TABLE "
|
||||
|
||||
sql += db.QuoteStr() + tableName + db.QuoteStr() + " ("
|
||||
sql += db.Quote(tableName) + " ("
|
||||
|
||||
pkList := table.PrimaryKeys
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func TestParseMSSQL(t *testing.T) {
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -220,7 +220,7 @@ func (db *mysql) SqlType(c *core.Column) string {
|
|||
case core.TimeStampz:
|
||||
res = core.Char
|
||||
c.Length = 64
|
||||
case core.Enum: //mysql enum
|
||||
case core.Enum: // mysql enum
|
||||
res = core.Enum
|
||||
res += "("
|
||||
opts := ""
|
||||
|
@ -229,7 +229,7 @@ func (db *mysql) SqlType(c *core.Column) string {
|
|||
}
|
||||
res += strings.TrimLeft(opts, ",")
|
||||
res += ")"
|
||||
case core.Set: //mysql set
|
||||
case core.Set: // mysql set
|
||||
res = core.Set
|
||||
res += "("
|
||||
opts := ""
|
||||
|
@ -278,10 +278,6 @@ func (db *mysql) Quote(name string) string {
|
|||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *mysql) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *mysql) SupportEngine() bool {
|
||||
return true
|
||||
}
|
||||
|
@ -360,7 +356,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
|||
var len1, len2 int
|
||||
if len(cts) == 2 {
|
||||
idx := strings.Index(cts[1], ")")
|
||||
if colType == core.Enum && cts[1][0] == '\'' { //enum
|
||||
if colType == core.Enum && cts[1][0] == '\'' { // enum
|
||||
options := strings.Split(cts[1][0:idx], ",")
|
||||
col.EnumOptions = make(map[string]int)
|
||||
for k, v := range options {
|
||||
|
@ -393,6 +389,9 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
|||
if colType == "FLOAT UNSIGNED" {
|
||||
colType = "FLOAT"
|
||||
}
|
||||
if colType == "DOUBLE UNSIGNED" {
|
||||
colType = "DOUBLE"
|
||||
}
|
||||
col.Length = len1
|
||||
col.Length2 = len2
|
||||
if _, ok := core.SqlTypes[colType]; ok {
|
||||
|
@ -405,7 +404,7 @@ func (db *mysql) GetColumns(tableName string) ([]string, map[string]*core.Column
|
|||
col.IsPrimaryKey = true
|
||||
}
|
||||
if colKey == "UNI" {
|
||||
//col.is
|
||||
// col.is
|
||||
}
|
||||
|
||||
if extra == "auto_increment" {
|
||||
|
@ -556,8 +555,6 @@ func (db *mysql) CreateTableSql(table *core.Table, tableName, storeEngine, chars
|
|||
sql += " DEFAULT CHARSET " + charset
|
||||
}
|
||||
|
||||
|
||||
|
||||
if db.rowFormat != "" {
|
||||
sql += " ROW_FORMAT=" + db.rowFormat
|
||||
}
|
||||
|
@ -630,7 +627,7 @@ func (p *mysqlDriver) Parse(driverName, dataSourceName string) (*core.Uri, error
|
|||
`\/(?P<dbname>.*?)` + // /dbname
|
||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
||||
// tlsConfigRegister := make(map[string]*tls.Config)
|
||||
names := dsnPattern.SubexpNames()
|
||||
|
||||
uri := &core.Uri{DbType: core.MYSQL}
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -552,11 +552,7 @@ func (db *oracle) IsReserved(name string) bool {
|
|||
}
|
||||
|
||||
func (db *oracle) Quote(name string) string {
|
||||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *oracle) QuoteStr() string {
|
||||
return "\""
|
||||
return "[" + name + "]"
|
||||
}
|
||||
|
||||
func (db *oracle) SupportEngine() bool {
|
||||
|
@ -596,7 +592,7 @@ func (db *oracle) CreateTableSql(table *core.Table, tableName, storeEngine, char
|
|||
sql += col.String(b.dialect)
|
||||
} else {*/
|
||||
sql += col.StringNoPk(db)
|
||||
//}
|
||||
// }
|
||||
sql = strings.TrimSpace(sql)
|
||||
sql += ", "
|
||||
}
|
||||
|
@ -865,7 +861,7 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, e
|
|||
`\/(?P<dbname>.*?)` + // /dbname
|
||||
`(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1¶mN=valueN]
|
||||
matches := dsnPattern.FindStringSubmatch(dataSourceName)
|
||||
//tlsConfigRegister := make(map[string]*tls.Config)
|
||||
// tlsConfigRegister := make(map[string]*tls.Config)
|
||||
names := dsnPattern.SubexpNames()
|
||||
|
||||
for i, match := range matches {
|
||||
|
@ -883,8 +879,8 @@ func (cfg *goracleDriver) Parse(driverName, dataSourceName string) (*core.Uri, e
|
|||
type oci8Driver struct {
|
||||
}
|
||||
|
||||
//dataSourceName=user/password@ipv4:port/dbname
|
||||
//dataSourceName=user/password@[ipv6]:port/dbname
|
||||
// dataSourceName=user/password@ipv4:port/dbname
|
||||
// dataSourceName=user/password@[ipv6]:port/dbname
|
||||
func (p *oci8Driver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||
db := &core.Uri{DbType: core.ORACLE}
|
||||
dsnPattern := regexp.MustCompile(
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// from http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html
|
||||
|
@ -863,10 +863,6 @@ func (db *postgres) Quote(name string) string {
|
|||
return "\"" + name + "\""
|
||||
}
|
||||
|
||||
func (db *postgres) QuoteStr() string {
|
||||
return "\""
|
||||
}
|
||||
|
||||
func (db *postgres) AutoIncrStr() string {
|
||||
return ""
|
||||
}
|
||||
|
@ -998,7 +994,7 @@ WHERE c.relkind = 'r'::char AND c.relname = $1%s AND f.attnum > 0 ORDER BY f.att
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
//fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, numPrecision, numRadix, isPK, isUnique)
|
||||
// fmt.Println(args, colName, isNullable, dataType, maxLenStr, colDefault, numPrecision, numRadix, isPK, isUnique)
|
||||
var maxLen int
|
||||
if maxLenStr != nil {
|
||||
maxLen, err = strconv.Atoi(*maxLenStr)
|
||||
|
@ -1093,7 +1089,6 @@ func (db *postgres) GetTables() ([]*core.Table, error) {
|
|||
return tables, nil
|
||||
}
|
||||
|
||||
|
||||
func getIndexColName(indexdef string) []string {
|
||||
var colNames []string
|
||||
|
||||
|
@ -1105,7 +1100,6 @@ func getIndexColName(indexdef string) []string {
|
|||
return colNames
|
||||
}
|
||||
|
||||
|
||||
func (db *postgres) GetIndexes(tableName string) (map[string]*core.Index, error) {
|
||||
args := []interface{}{tableName}
|
||||
s := fmt.Sprintf("SELECT indexname, indexdef FROM pg_indexes WHERE tablename=$1")
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/jackc/pgx/stdlib"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -202,10 +202,6 @@ func (db *sqlite3) Quote(name string) string {
|
|||
return "`" + name + "`"
|
||||
}
|
||||
|
||||
func (db *sqlite3) QuoteStr() string {
|
||||
return "`"
|
||||
}
|
||||
|
||||
func (db *sqlite3) AutoIncrStr() string {
|
||||
return "AUTOINCREMENT"
|
||||
}
|
||||
|
|
77
engine.go
77
engine.go
|
@ -20,8 +20,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Engine is the major struct of xorm, it means a database manager.
|
||||
|
@ -125,6 +125,7 @@ func (engine *Engine) Logger() core.ILogger {
|
|||
// SetLogger set the new logger
|
||||
func (engine *Engine) SetLogger(logger core.ILogger) {
|
||||
engine.logger = logger
|
||||
engine.showSQL = logger.IsShowSQL()
|
||||
engine.dialect.SetLogger(logger)
|
||||
}
|
||||
|
||||
|
@ -174,12 +175,6 @@ func (engine *Engine) SupportInsertMany() bool {
|
|||
return engine.dialect.SupportInsertMany()
|
||||
}
|
||||
|
||||
// QuoteStr Engine's database use which character as quote.
|
||||
// mysql, sqlite use ` and postgres use "
|
||||
func (engine *Engine) QuoteStr() string {
|
||||
return engine.dialect.QuoteStr()
|
||||
}
|
||||
|
||||
func (engine *Engine) quoteColumns(columnStr string) string {
|
||||
columns := strings.Split(columnStr, ",")
|
||||
for i := 0; i < len(columns); i++ {
|
||||
|
@ -195,13 +190,10 @@ func (engine *Engine) Quote(value string) string {
|
|||
return value
|
||||
}
|
||||
|
||||
if string(value[0]) == engine.dialect.QuoteStr() || value[0] == '`' {
|
||||
return value
|
||||
}
|
||||
buf := builder.StringBuilder{}
|
||||
engine.QuoteTo(&buf, value)
|
||||
|
||||
value = strings.Replace(value, ".", engine.dialect.QuoteStr()+"."+engine.dialect.QuoteStr(), -1)
|
||||
|
||||
return engine.dialect.QuoteStr() + value + engine.dialect.QuoteStr()
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// QuoteTo quotes string and writes into the buffer
|
||||
|
@ -215,20 +207,30 @@ func (engine *Engine) QuoteTo(buf *builder.StringBuilder, value string) {
|
|||
return
|
||||
}
|
||||
|
||||
if string(value[0]) == engine.dialect.QuoteStr() || value[0] == '`' {
|
||||
buf.WriteString(value)
|
||||
quotePair := engine.dialect.Quote("")
|
||||
|
||||
if value[0] == '`' || len(quotePair) < 2 || value[0] == quotePair[0] { // no quote
|
||||
_, _ = buf.WriteString(value)
|
||||
return
|
||||
} else {
|
||||
prefix, suffix := quotePair[0], quotePair[1]
|
||||
|
||||
_ = buf.WriteByte(prefix)
|
||||
for i := 0; i < len(value); i++ {
|
||||
if value[i] == '.' {
|
||||
_ = buf.WriteByte(suffix)
|
||||
_ = buf.WriteByte('.')
|
||||
_ = buf.WriteByte(prefix)
|
||||
} else {
|
||||
_ = buf.WriteByte(value[i])
|
||||
}
|
||||
}
|
||||
_ = buf.WriteByte(suffix)
|
||||
}
|
||||
|
||||
value = strings.Replace(value, ".", engine.dialect.QuoteStr()+"."+engine.dialect.QuoteStr(), -1)
|
||||
|
||||
buf.WriteString(engine.dialect.QuoteStr())
|
||||
buf.WriteString(value)
|
||||
buf.WriteString(engine.dialect.QuoteStr())
|
||||
}
|
||||
|
||||
func (engine *Engine) quote(sql string) string {
|
||||
return engine.dialect.QuoteStr() + sql + engine.dialect.QuoteStr()
|
||||
return engine.dialect.Quote(sql)
|
||||
}
|
||||
|
||||
// SqlType will be deprecated, please use SQLType instead
|
||||
|
@ -922,7 +924,16 @@ func (engine *Engine) mapType(v reflect.Value) (*core.Table, error) {
|
|||
engine: engine,
|
||||
}
|
||||
|
||||
if strings.ToUpper(tags[0]) == "EXTENDS" {
|
||||
if strings.HasPrefix(strings.ToUpper(tags[0]), "EXTENDS") {
|
||||
pStart := strings.Index(tags[0], "(")
|
||||
if pStart > -1 && strings.HasSuffix(tags[0], ")") {
|
||||
var tagPrefix = strings.TrimFunc(tags[0][pStart+1:len(tags[0])-1], func(r rune) bool {
|
||||
return r == '\'' || r == '"'
|
||||
})
|
||||
|
||||
ctx.params = []string{tagPrefix}
|
||||
}
|
||||
|
||||
if err := ExtendsTagHandler(&ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1354,31 +1365,31 @@ func (engine *Engine) DropIndexes(bean interface{}) error {
|
|||
}
|
||||
|
||||
// Exec raw sql
|
||||
func (engine *Engine) Exec(sqlorArgs ...interface{}) (sql.Result, error) {
|
||||
func (engine *Engine) Exec(sqlOrArgs ...interface{}) (sql.Result, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Exec(sqlorArgs...)
|
||||
return session.Exec(sqlOrArgs...)
|
||||
}
|
||||
|
||||
// Query a raw sql and return records as []map[string][]byte
|
||||
func (engine *Engine) Query(sqlorArgs ...interface{}) (resultsSlice []map[string][]byte, err error) {
|
||||
func (engine *Engine) Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.Query(sqlorArgs...)
|
||||
return session.Query(sqlOrArgs...)
|
||||
}
|
||||
|
||||
// QueryString runs a raw sql and return records as []map[string]string
|
||||
func (engine *Engine) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) {
|
||||
func (engine *Engine) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.QueryString(sqlorArgs...)
|
||||
return session.QueryString(sqlOrArgs...)
|
||||
}
|
||||
|
||||
// QueryInterface runs a raw sql and return records as []map[string]interface{}
|
||||
func (engine *Engine) QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) {
|
||||
func (engine *Engine) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) {
|
||||
session := engine.NewSession()
|
||||
defer session.Close()
|
||||
return session.QueryInterface(sqlorArgs...)
|
||||
return session.QueryInterface(sqlOrArgs...)
|
||||
}
|
||||
|
||||
// Insert one or more records
|
||||
|
@ -1571,7 +1582,7 @@ func (engine *Engine) formatColTime(col *core.Column, t time.Time) (v interface{
|
|||
func (engine *Engine) formatTime(sqlTypeName string, t time.Time) (v interface{}) {
|
||||
switch sqlTypeName {
|
||||
case core.Time:
|
||||
s := t.Format("2006-01-02 15:04:05") //time.RFC3339
|
||||
s := t.Format("2006-01-02 15:04:05") // time.RFC3339
|
||||
v = s[11:19]
|
||||
case core.Date:
|
||||
v = t.Format("2006-01-02")
|
||||
|
|
|
@ -6,14 +6,13 @@ package xorm
|
|||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
||||
|
@ -147,7 +146,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
|||
} else {
|
||||
if col.SQLType.IsJson() {
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
continue
|
||||
|
@ -156,7 +155,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
|||
} else if col.SQLType.IsBlob() {
|
||||
var bytes []byte
|
||||
var err error
|
||||
bytes, err = json.Marshal(fieldValue.Interface())
|
||||
bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
continue
|
||||
|
@ -195,7 +194,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
|||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
continue
|
||||
|
@ -212,7 +211,7 @@ func (engine *Engine) buildConds(table *core.Table, bean interface{},
|
|||
continue
|
||||
}
|
||||
} else {
|
||||
bytes, err = json.Marshal(fieldValue.Interface())
|
||||
bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
continue
|
||||
|
|
|
@ -20,6 +20,8 @@ func TestPingContext(t *testing.T) {
|
|||
ctx, canceled := context.WithTimeout(context.Background(), time.Nanosecond)
|
||||
defer canceled()
|
||||
|
||||
time.Sleep(time.Nanosecond)
|
||||
|
||||
err := testEngine.(*Engine).PingContext(ctx)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "context deadline exceeded")
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
package xorm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// EngineGroup defines an engine group
|
||||
|
@ -74,6 +75,13 @@ func (eg *EngineGroup) Close() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Context returned a group session
|
||||
func (eg *EngineGroup) Context(ctx context.Context) *Session {
|
||||
sess := eg.NewSession()
|
||||
sess.isAutoClose = true
|
||||
return sess.Context(ctx)
|
||||
}
|
||||
|
||||
// NewSession returned a group session
|
||||
func (eg *EngineGroup) NewSession() *Session {
|
||||
sess := eg.Engine.NewSession()
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// tbNameWithSchema will automatically add schema prefix on table name
|
||||
|
|
16
go.mod
16
go.mod
|
@ -1,29 +1,19 @@
|
|||
module github.com/go-xorm/xorm
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.34.0 // indirect
|
||||
github.com/cockroachdb/apd v1.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4
|
||||
github.com/go-sql-driver/mysql v1.4.1
|
||||
github.com/go-xorm/builder v0.3.3
|
||||
github.com/go-xorm/core v0.6.2
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a // indirect
|
||||
github.com/google/go-cmp v0.2.0 // indirect
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
||||
github.com/jackc/pgx v3.3.0+incompatible
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/kr/pty v1.1.3 // indirect
|
||||
github.com/lib/pq v1.0.0
|
||||
github.com/mattn/go-sqlite3 v1.10.0
|
||||
github.com/pkg/errors v0.8.1 // indirect
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
|
||||
github.com/stretchr/objx v0.1.1 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/ziutek/mymysql v1.5.4
|
||||
golang.org/x/crypto v0.0.0-20190122013713-64072686203f // indirect
|
||||
golang.org/x/net v0.0.0-20190110200230-915654e7eabc // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2
|
||||
xorm.io/builder v0.3.5
|
||||
xorm.io/core v0.7.0
|
||||
)
|
||||
|
|
123
go.sum
123
go.sum
|
@ -1,60 +1,159 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.37.4 h1:glPeL3BQJsbF6aIIYfZizMwc5LTYz250bDMjttbBGAU=
|
||||
cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952 h1:b5OnbZD49x9g+/FcYbs/vukEt8C/jUbGhCJ3uduQmu8=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190121005146-b04fd42d9952/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4 h1:YcpmyvADGYw5LqMnHqSkyIELsHCGF6PkrmM31V8rF7o=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-xorm/builder v0.3.3 h1:v8grgrwOGv/iHXIEhIvOwHZIPLrpxRKSX8yWSMLFn/4=
|
||||
github.com/go-xorm/builder v0.3.3/go.mod h1:v8mE3MFBgtL+RGFNfUnAMUqqfk/Y4W5KuwCFQIEpQLk=
|
||||
github.com/go-xorm/core v0.6.2 h1:EJLcSxf336POJr670wKB55Mah9f93xzvGYzNRgnT8/Y=
|
||||
github.com/go-xorm/core v0.6.2/go.mod h1:bwPIfLdm/FzWgVUH8WPVlr+uJhscvNGFcaZKXsI3n2c=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||
github.com/jackc/pgx v3.3.0+incompatible h1:Wa90/+qsITBAPkAZjiByeIGHFcj3Ztu+VzrrIpHjL90=
|
||||
github.com/jackc/pgx v3.3.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
golang.org/x/crypto v0.0.0-20190122013713-64072686203f h1:u1CmMhe3a44hy8VIgpInORnI01UVaUYheqR7x9BxT3c=
|
||||
golang.org/x/crypto v0.0.0-20190122013713-64072686203f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI=
|
||||
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190110200230-915654e7eabc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2 h1:yhQC6Uy5CqibAIlk1wlusa/MJ3iAN49/BsR/dCCKz3M=
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2/go.mod h1:QI5V/q6UbPmuhtm10CaFZxED9NreB8PnFYN9JcR6TxU=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
xorm.io/builder v0.3.5 h1:EilU39fvWDxjb1cDaELpYhsF+zziRBhew8xk4pngO+A=
|
||||
xorm.io/builder v0.3.5/go.mod h1:ZFbByS/KxZI1FKRjL05PyJ4YrK2bcxlUaAxdum5aTR8=
|
||||
xorm.io/core v0.6.3 h1:n1NhVZt1s2oLw1BZfX2ocIJsHyso259uPgg63BGr37M=
|
||||
xorm.io/core v0.6.3/go.mod h1:8kz/C6arVW/O9vk3PgCiMJO2hIAm1UcuOL3dSPyZ2qo=
|
||||
|
|
25
helpers.go
25
helpers.go
|
@ -12,7 +12,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// str2PK convert string value to primary key value according to tp
|
||||
|
@ -281,7 +281,7 @@ func rValue(bean interface{}) reflect.Value {
|
|||
|
||||
func rType(bean interface{}) reflect.Type {
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
//return reflect.TypeOf(sliceValue.Interface())
|
||||
// return reflect.TypeOf(sliceValue.Interface())
|
||||
return sliceValue.Type()
|
||||
}
|
||||
|
||||
|
@ -309,3 +309,24 @@ func sliceEq(left, right []string) bool {
|
|||
func indexName(tableName, idxName string) string {
|
||||
return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
|
||||
}
|
||||
|
||||
func eraseAny(value string, strToErase ...string) string {
|
||||
if len(strToErase) == 0 {
|
||||
return value
|
||||
}
|
||||
var replaceSeq []string
|
||||
for _, s := range strToErase {
|
||||
replaceSeq = append(replaceSeq, s, "")
|
||||
}
|
||||
|
||||
replacer := strings.NewReplacer(replaceSeq...)
|
||||
|
||||
return replacer.Replace(value)
|
||||
}
|
||||
|
||||
func quoteColumns(cols []string, quoteFunc func(string) string, sep string) string {
|
||||
for i := range cols {
|
||||
cols[i] = quoteFunc(cols[i])
|
||||
}
|
||||
return strings.Join(cols, sep+" ")
|
||||
}
|
||||
|
|
|
@ -4,7 +4,11 @@
|
|||
|
||||
package xorm
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSplitTag(t *testing.T) {
|
||||
var cases = []struct {
|
||||
|
@ -24,3 +28,19 @@ func TestSplitTag(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEraseAny(t *testing.T) {
|
||||
raw := "SELECT * FROM `table`.[table_name]"
|
||||
assert.EqualValues(t, raw, eraseAny(raw))
|
||||
assert.EqualValues(t, "SELECT * FROM table.[table_name]", eraseAny(raw, "`"))
|
||||
assert.EqualValues(t, "SELECT * FROM table.table_name", eraseAny(raw, "`", "[", "]"))
|
||||
}
|
||||
|
||||
func TestQuoteColumns(t *testing.T) {
|
||||
cols := []string{"f1", "f2", "f3"}
|
||||
quoteFunc := func(value string) string {
|
||||
return "[" + value + "]"
|
||||
}
|
||||
|
||||
assert.EqualValues(t, "[f1], [f2], [f3]", quoteColumns(cols, quoteFunc, ","))
|
||||
}
|
||||
|
|
10
interface.go
10
interface.go
|
@ -10,7 +10,7 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Interface defines the interface which Engine, EngineGroup and Session will implementate.
|
||||
|
@ -28,7 +28,7 @@ type Interface interface {
|
|||
Delete(interface{}) (int64, error)
|
||||
Distinct(columns ...string) *Session
|
||||
DropIndexes(bean interface{}) error
|
||||
Exec(sqlOrAgrs ...interface{}) (sql.Result, error)
|
||||
Exec(sqlOrArgs ...interface{}) (sql.Result, error)
|
||||
Exist(bean ...interface{}) (bool, error)
|
||||
Find(interface{}, ...interface{}) error
|
||||
FindAndCount(interface{}, ...interface{}) (int64, error)
|
||||
|
@ -50,9 +50,9 @@ type Interface interface {
|
|||
Omit(columns ...string) *Session
|
||||
OrderBy(order string) *Session
|
||||
Ping() error
|
||||
Query(sqlOrAgrs ...interface{}) (resultsSlice []map[string][]byte, err error)
|
||||
QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error)
|
||||
QueryString(sqlorArgs ...interface{}) ([]map[string]string, error)
|
||||
Query(sqlOrArgs ...interface{}) (resultsSlice []map[string][]byte, err error)
|
||||
QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error)
|
||||
QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error)
|
||||
Rows(bean interface{}) (*Rows, error)
|
||||
SetExpr(string, string) *Session
|
||||
SQL(interface{}, ...interface{}) *Session
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2019 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 "encoding/json"
|
||||
|
||||
// JSONInterface represents an interface to handle json data
|
||||
type JSONInterface interface {
|
||||
Marshal(v interface{}) ([]byte, error)
|
||||
Unmarshal(data []byte, v interface{}) error
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultJSONHandler default json handler
|
||||
DefaultJSONHandler JSONInterface = StdJSON{}
|
||||
)
|
||||
|
||||
// StdJSON implements JSONInterface via encoding/json
|
||||
type StdJSON struct{}
|
||||
|
||||
// Marshal implements JSONInterface
|
||||
func (StdJSON) Marshal(v interface{}) ([]byte, error) {
|
||||
return json.Marshal(v)
|
||||
}
|
||||
|
||||
// Unmarshal implements JSONInterface
|
||||
func (StdJSON) Unmarshal(data []byte, v interface{}) error {
|
||||
return json.Unmarshal(data, v)
|
||||
}
|
|
@ -9,7 +9,7 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// default log options
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/go-xorm/xorm"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"gopkg.in/stretchr/testify.v1/assert"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type Person struct {
|
||||
|
|
14
rows.go
14
rows.go
|
@ -9,7 +9,7 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Rows rows wrapper a rows to
|
||||
|
@ -113,17 +113,9 @@ func (rows *Rows) Close() error {
|
|||
defer rows.session.Close()
|
||||
}
|
||||
|
||||
if rows.lastError == nil {
|
||||
if rows.rows != nil {
|
||||
rows.lastError = rows.rows.Close()
|
||||
if rows.lastError != nil {
|
||||
return rows.lastError
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if rows.rows != nil {
|
||||
defer rows.rows.Close()
|
||||
}
|
||||
return rows.rows.Close()
|
||||
}
|
||||
|
||||
return rows.lastError
|
||||
}
|
||||
|
|
16
rows_test.go
16
rows_test.go
|
@ -38,6 +38,22 @@ func TestRows(t *testing.T) {
|
|||
cnt++
|
||||
}
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
assert.False(t, rows.Next())
|
||||
assert.NoError(t, rows.Close())
|
||||
|
||||
rows0, err := testEngine.Where("1>1").Rows(new(UserRows))
|
||||
assert.NoError(t, err)
|
||||
defer rows0.Close()
|
||||
|
||||
cnt = 0
|
||||
user0 := new(UserRows)
|
||||
for rows0.Next() {
|
||||
err = rows0.Scan(user0)
|
||||
assert.NoError(t, err)
|
||||
cnt++
|
||||
}
|
||||
assert.EqualValues(t, 0, cnt)
|
||||
assert.NoError(t, rows0.Close())
|
||||
|
||||
sess := testEngine.NewSession()
|
||||
defer sess.Close()
|
||||
|
|
21
session.go
21
session.go
|
@ -7,7 +7,6 @@ package xorm
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
|
@ -15,7 +14,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
type sessionType int
|
||||
|
@ -491,13 +490,13 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
continue
|
||||
}
|
||||
if fieldValue.CanAddr() {
|
||||
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(bs, x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(bs, x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -521,13 +520,13 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
hasAssigned = true
|
||||
if len(bs) > 0 {
|
||||
if fieldValue.CanAddr() {
|
||||
err := json.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(bs, fieldValue.Addr().Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(bs, x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(bs, x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -543,7 +542,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
hasAssigned = true
|
||||
if col.SQLType.IsText() {
|
||||
x := reflect.New(fieldType)
|
||||
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -658,7 +657,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
hasAssigned = true
|
||||
x := reflect.New(fieldType)
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -668,7 +667,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
hasAssigned = true
|
||||
x := reflect.New(fieldType)
|
||||
if len(vv.Bytes()) > 0 {
|
||||
err := json.Unmarshal(vv.Bytes(), x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(vv.Bytes(), x.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -804,7 +803,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
case core.Complex64Type:
|
||||
var x complex64
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), &x)
|
||||
err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -814,7 +813,7 @@ func (session *Session) slice2Bean(scanResults []interface{}, fields []string, b
|
|||
case core.Complex128Type:
|
||||
var x complex128
|
||||
if len([]byte(vv.String())) > 0 {
|
||||
err := json.Unmarshal([]byte(vv.String()), &x)
|
||||
err := DefaultJSONHandler.Unmarshal([]byte(vv.String()), &x)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
type incrParam struct {
|
||||
|
|
|
@ -7,7 +7,7 @@ package xorm
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
package xorm
|
||||
|
||||
import "github.com/go-xorm/builder"
|
||||
import "xorm.io/builder"
|
||||
|
||||
// Sql provides raw sql input parameter. When you have a complex SQL statement
|
||||
// and cannot use Where, Id, In and etc. Methods to describe, you can use SQL.
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"xorm.io/builder"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -26,6 +26,9 @@ func TestQueryContext(t *testing.T) {
|
|||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
|
||||
defer cancel()
|
||||
|
||||
time.Sleep(time.Nanosecond)
|
||||
|
||||
has, err := testEngine.Context(ctx).Exist(&ContextQueryStruct{Name: "1"})
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "context deadline exceeded")
|
||||
|
|
|
@ -7,7 +7,6 @@ package xorm
|
|||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
@ -15,7 +14,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func (session *Session) str2Time(col *core.Column, data string) (outTime time.Time, outErr error) {
|
||||
|
@ -103,7 +102,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
|||
case reflect.Complex64, reflect.Complex128:
|
||||
x := reflect.New(fieldType)
|
||||
if len(data) > 0 {
|
||||
err := json.Unmarshal(data, x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(data, x.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return err
|
||||
|
@ -117,7 +116,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
|||
if col.SQLType.IsText() {
|
||||
x := reflect.New(fieldType)
|
||||
if len(data) > 0 {
|
||||
err := json.Unmarshal(data, x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(data, x.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return err
|
||||
|
@ -130,7 +129,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
|||
} else {
|
||||
x := reflect.New(fieldType)
|
||||
if len(data) > 0 {
|
||||
err := json.Unmarshal(data, x.Interface())
|
||||
err := DefaultJSONHandler.Unmarshal(data, x.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return err
|
||||
|
@ -259,7 +258,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
|||
case core.Complex64Type.Kind():
|
||||
var x complex64
|
||||
if len(data) > 0 {
|
||||
err := json.Unmarshal(data, &x)
|
||||
err := DefaultJSONHandler.Unmarshal(data, &x)
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return err
|
||||
|
@ -270,7 +269,7 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
|||
case core.Complex128Type.Kind():
|
||||
var x complex128
|
||||
if len(data) > 0 {
|
||||
err := json.Unmarshal(data, &x)
|
||||
err := DefaultJSONHandler.Unmarshal(data, &x)
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return err
|
||||
|
@ -604,14 +603,14 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
|||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return 0, err
|
||||
}
|
||||
return string(bytes), nil
|
||||
} else if col.SQLType.IsBlob() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return 0, err
|
||||
|
@ -620,7 +619,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
|||
}
|
||||
return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type())
|
||||
case reflect.Complex64, reflect.Complex128:
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return 0, err
|
||||
|
@ -632,7 +631,7 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
|||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return 0, err
|
||||
|
@ -641,11 +640,11 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
|||
} else if col.SQLType.IsBlob() {
|
||||
var bytes []byte
|
||||
var err error
|
||||
if (k == reflect.Array || k == reflect.Slice) &&
|
||||
if (k == reflect.Slice) &&
|
||||
(fieldValue.Type().Elem().Kind() == reflect.Uint8) {
|
||||
bytes = fieldValue.Bytes()
|
||||
} else {
|
||||
bytes, err = json.Marshal(fieldValue.Interface())
|
||||
bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
session.engine.logger.Error(err)
|
||||
return 0, err
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Exist returns true if the record exist otherwise return false
|
||||
|
@ -34,6 +34,8 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
|||
return false, ErrTableNotFound
|
||||
}
|
||||
|
||||
tableName = session.statement.Engine.Quote(tableName)
|
||||
|
||||
if session.statement.cond.IsValid() {
|
||||
condSQL, condArgs, err := builder.ToSQL(session.statement.cond)
|
||||
if err != nil {
|
||||
|
@ -42,6 +44,8 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
|||
|
||||
if session.engine.dialect.DBType() == core.MSSQL {
|
||||
sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s WHERE %s", tableName, condSQL)
|
||||
} else if session.engine.dialect.DBType() == core.ORACLE {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE (%s) AND ROWNUM=1", tableName, condSQL)
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT 1", tableName, condSQL)
|
||||
}
|
||||
|
@ -49,6 +53,8 @@ func (session *Session) Exist(bean ...interface{}) (bool, error) {
|
|||
} else {
|
||||
if session.engine.dialect.DBType() == core.MSSQL {
|
||||
sqlStr = fmt.Sprintf("SELECT TOP 1 * FROM %s", tableName)
|
||||
} else if session.engine.dialect.DBType() == core.ORACLE {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s WHERE ROWNUM=1", tableName)
|
||||
} else {
|
||||
sqlStr = fmt.Sprintf("SELECT * FROM %s LIMIT 1", tableName)
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
113
session_get.go
113
session_get.go
|
@ -11,7 +11,7 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Get retrieve one record from database, bean's non-empty fields
|
||||
|
@ -114,6 +114,114 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
|||
return true, rows.Scan(&bean)
|
||||
case *sql.NullInt64, *sql.NullBool, *sql.NullFloat64, *sql.NullString:
|
||||
return true, rows.Scan(bean)
|
||||
case *string:
|
||||
var res sql.NullString
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*string)) = res.String
|
||||
}
|
||||
return true, nil
|
||||
case *int:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int)) = int(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int8:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int8)) = int8(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int16:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int16)) = int16(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int32:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int32)) = int32(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *int64:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*int64)) = int64(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint)) = uint(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint8:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint8)) = uint8(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint16:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint16)) = uint16(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint32:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint32)) = uint32(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *uint64:
|
||||
var res sql.NullInt64
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*uint64)) = uint64(res.Int64)
|
||||
}
|
||||
return true, nil
|
||||
case *bool:
|
||||
var res sql.NullBool
|
||||
if err := rows.Scan(&res); err != nil {
|
||||
return true, err
|
||||
}
|
||||
if res.Valid {
|
||||
*(bean.(*bool)) = res.Bool
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
switch beanKind {
|
||||
|
@ -142,6 +250,9 @@ func (session *Session) nocacheGet(beanKind reflect.Kind, table *core.Table, bea
|
|||
err = rows.ScanSlice(bean)
|
||||
case reflect.Map:
|
||||
err = rows.ScanMap(bean)
|
||||
case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
err = rows.Scan(&bean)
|
||||
default:
|
||||
err = rows.Scan(bean)
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func TestGetVar(t *testing.T) {
|
||||
|
@ -47,6 +47,12 @@ func TestGetVar(t *testing.T) {
|
|||
assert.Equal(t, true, has)
|
||||
assert.Equal(t, 28, age)
|
||||
|
||||
var ageMax int
|
||||
has, err = testEngine.SQL("SELECT max(age) FROM "+testEngine.TableName("get_var", true)+" WHERE `id` = ?", data.Id).Get(&ageMax)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.Equal(t, 28, ageMax)
|
||||
|
||||
var age2 int64
|
||||
has, err = testEngine.Table("get_var").Cols("age").
|
||||
Where("age > ?", 20).
|
||||
|
@ -56,6 +62,69 @@ func TestGetVar(t *testing.T) {
|
|||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age2)
|
||||
|
||||
var age3 int8
|
||||
has, err = testEngine.Table("get_var").Cols("age").Get(&age3)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age3)
|
||||
|
||||
var age4 int16
|
||||
has, err = testEngine.Table("get_var").Cols("age").
|
||||
Where("age > ?", 20).
|
||||
And("age < ?", 30).
|
||||
Get(&age4)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age4)
|
||||
|
||||
var age5 int32
|
||||
has, err = testEngine.Table("get_var").Cols("age").
|
||||
Where("age > ?", 20).
|
||||
And("age < ?", 30).
|
||||
Get(&age5)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age5)
|
||||
|
||||
var age6 int
|
||||
has, err = testEngine.Table("get_var").Cols("age").Get(&age6)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age6)
|
||||
|
||||
var age7 int64
|
||||
has, err = testEngine.Table("get_var").Cols("age").
|
||||
Where("age > ?", 20).
|
||||
And("age < ?", 30).
|
||||
Get(&age7)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age7)
|
||||
|
||||
var age8 int8
|
||||
has, err = testEngine.Table("get_var").Cols("age").Get(&age8)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age8)
|
||||
|
||||
var age9 int16
|
||||
has, err = testEngine.Table("get_var").Cols("age").
|
||||
Where("age > ?", 20).
|
||||
And("age < ?", 30).
|
||||
Get(&age9)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age9)
|
||||
|
||||
var age10 int32
|
||||
has, err = testEngine.Table("get_var").Cols("age").
|
||||
Where("age > ?", 20).
|
||||
And("age < ?", 30).
|
||||
Get(&age10)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, true, has)
|
||||
assert.EqualValues(t, 28, age10)
|
||||
|
||||
var id sql.NullInt64
|
||||
has, err = testEngine.Table("get_var").Cols("id").Get(&id)
|
||||
assert.NoError(t, err)
|
||||
|
@ -433,3 +502,85 @@ func TestGetCustomTableInterface(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
}
|
||||
|
||||
func TestGetNullVar(t *testing.T) {
|
||||
type TestGetNullVarStruct struct {
|
||||
Id int64
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
assert.NoError(t, prepareEngine())
|
||||
assertSync(t, new(TestGetNullVarStruct))
|
||||
|
||||
affected, err := testEngine.Exec("insert into " + testEngine.TableName(new(TestGetNullVarStruct), true) + " (name,age) values (null,null)")
|
||||
assert.NoError(t, err)
|
||||
a, _ := affected.RowsAffected()
|
||||
assert.EqualValues(t, 1, a)
|
||||
|
||||
var name string
|
||||
has, err := testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("name").Get(&name)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, "", name)
|
||||
|
||||
var age int
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age)
|
||||
|
||||
var age2 int8
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age2)
|
||||
|
||||
var age3 int16
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age3)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age3)
|
||||
|
||||
var age4 int32
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age4)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age4)
|
||||
|
||||
var age5 int64
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age5)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age5)
|
||||
|
||||
var age6 uint
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age6)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age6)
|
||||
|
||||
var age7 uint8
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age7)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age7)
|
||||
|
||||
var age8 int16
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age8)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age8)
|
||||
|
||||
var age9 int32
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age9)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age9)
|
||||
|
||||
var age10 int64
|
||||
has, err = testEngine.Table(new(TestGetNullVarStruct)).Where("id = ?", 1).Cols("age").Get(&age10)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, has)
|
||||
assert.EqualValues(t, 0, age10)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Insert insert one or more beans
|
||||
|
@ -242,23 +242,17 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
|||
|
||||
var sql string
|
||||
if session.engine.dialect.DBType() == core.ORACLE {
|
||||
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
||||
temp := fmt.Sprintf(") INTO %s (%v) VALUES (",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr())
|
||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||
quoteColumns(colNames, session.engine.Quote, ","))
|
||||
sql = fmt.Sprintf("INSERT ALL INTO %s (%v) VALUES (%v) SELECT 1 FROM DUAL",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr(),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
strings.Join(colMultiPlaces, temp))
|
||||
} else {
|
||||
sql = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
||||
sql = fmt.Sprintf("INSERT INTO %s (%v) VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||
session.engine.QuoteStr(),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
strings.Join(colMultiPlaces, "),("))
|
||||
}
|
||||
res, err := session.exec(sql, args...)
|
||||
|
@ -378,11 +372,9 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
|||
output = fmt.Sprintf(" OUTPUT Inserted.%s", table.AutoIncrement)
|
||||
}
|
||||
if len(colPlaces) > 0 {
|
||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v)%s VALUES (%v)",
|
||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v)%s VALUES (%v)",
|
||||
session.engine.Quote(tableName),
|
||||
session.engine.QuoteStr(),
|
||||
strings.Join(colNames, session.engine.Quote(", ")),
|
||||
session.engine.QuoteStr(),
|
||||
quoteColumns(colNames, session.engine.Quote, ","),
|
||||
output,
|
||||
colPlaces)
|
||||
} else {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interface{}, error) {
|
||||
if len(sqlorArgs) > 0 {
|
||||
return convertSQLOrArgs(sqlorArgs...)
|
||||
func (session *Session) genQuerySQL(sqlOrArgs ...interface{}) (string, []interface{}, error) {
|
||||
if len(sqlOrArgs) > 0 {
|
||||
return convertSQLOrArgs(sqlOrArgs...)
|
||||
}
|
||||
|
||||
if session.statement.RawSQL != "" {
|
||||
|
@ -78,12 +78,12 @@ func (session *Session) genQuerySQL(sqlorArgs ...interface{}) (string, []interfa
|
|||
}
|
||||
|
||||
// Query runs a raw sql and return records as []map[string][]byte
|
||||
func (session *Session) Query(sqlorArgs ...interface{}) ([]map[string][]byte, error) {
|
||||
func (session *Session) Query(sqlOrArgs ...interface{}) ([]map[string][]byte, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
|
||||
sqlStr, args, err := session.genQuerySQL(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -227,12 +227,12 @@ func rows2SliceString(rows *core.Rows) (resultsSlice [][]string, err error) {
|
|||
}
|
||||
|
||||
// QueryString runs a raw sql and return records as []map[string]string
|
||||
func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]string, error) {
|
||||
func (session *Session) QueryString(sqlOrArgs ...interface{}) ([]map[string]string, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
|
||||
sqlStr, args, err := session.genQuerySQL(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -247,12 +247,12 @@ func (session *Session) QueryString(sqlorArgs ...interface{}) ([]map[string]stri
|
|||
}
|
||||
|
||||
// QuerySliceString runs a raw sql and return records as [][]string
|
||||
func (session *Session) QuerySliceString(sqlorArgs ...interface{}) ([][]string, error) {
|
||||
func (session *Session) QuerySliceString(sqlOrArgs ...interface{}) ([][]string, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
|
||||
sqlStr, args, err := session.genQuerySQL(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -300,12 +300,12 @@ func rows2Interfaces(rows *core.Rows) (resultsSlice []map[string]interface{}, er
|
|||
}
|
||||
|
||||
// QueryInterface runs a raw sql and return records as []map[string]interface{}
|
||||
func (session *Session) QueryInterface(sqlorArgs ...interface{}) ([]map[string]interface{}, error) {
|
||||
func (session *Session) QueryInterface(sqlOrArgs ...interface{}) ([]map[string]interface{}, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
sqlStr, args, err := session.genQuerySQL(sqlorArgs...)
|
||||
sqlStr, args, err := session.genQuerySQL(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func (session *Session) queryPreprocess(sqlStr *string, paramStr ...interface{}) {
|
||||
|
@ -194,14 +194,14 @@ func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, er
|
|||
return session.DB().ExecContext(session.ctx, sqlStr, args...)
|
||||
}
|
||||
|
||||
func convertSQLOrArgs(sqlorArgs ...interface{}) (string, []interface{}, error) {
|
||||
switch sqlorArgs[0].(type) {
|
||||
func convertSQLOrArgs(sqlOrArgs ...interface{}) (string, []interface{}, error) {
|
||||
switch sqlOrArgs[0].(type) {
|
||||
case string:
|
||||
return sqlorArgs[0].(string), sqlorArgs[1:], nil
|
||||
return sqlOrArgs[0].(string), sqlOrArgs[1:], nil
|
||||
case *builder.Builder:
|
||||
return sqlorArgs[0].(*builder.Builder).ToSQL()
|
||||
return sqlOrArgs[0].(*builder.Builder).ToSQL()
|
||||
case builder.Builder:
|
||||
bd := sqlorArgs[0].(builder.Builder)
|
||||
bd := sqlOrArgs[0].(builder.Builder)
|
||||
return bd.ToSQL()
|
||||
}
|
||||
|
||||
|
@ -209,16 +209,16 @@ func convertSQLOrArgs(sqlorArgs ...interface{}) (string, []interface{}, error) {
|
|||
}
|
||||
|
||||
// Exec raw sql
|
||||
func (session *Session) Exec(sqlorArgs ...interface{}) (sql.Result, error) {
|
||||
func (session *Session) Exec(sqlOrArgs ...interface{}) (sql.Result, error) {
|
||||
if session.isAutoClose {
|
||||
defer session.Close()
|
||||
}
|
||||
|
||||
if len(sqlorArgs) == 0 {
|
||||
if len(sqlOrArgs) == 0 {
|
||||
return nil, ErrUnSupportedType
|
||||
}
|
||||
|
||||
sqlStr, args, err := convertSQLOrArgs(sqlorArgs...)
|
||||
sqlStr, args, err := convertSQLOrArgs(sqlOrArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Ping test if database is ok
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"xorm.io/builder"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
|
||||
|
@ -96,14 +96,15 @@ func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string,
|
|||
return ErrCacheFailed
|
||||
}
|
||||
kvs := strings.Split(strings.TrimSpace(sqls[1]), ",")
|
||||
|
||||
for idx, kv := range kvs {
|
||||
sps := strings.SplitN(kv, "=", 2)
|
||||
sps2 := strings.Split(sps[0], ".")
|
||||
colName := sps2[len(sps2)-1]
|
||||
if strings.Contains(colName, "`") {
|
||||
colName = strings.TrimSpace(strings.Replace(colName, "`", "", -1))
|
||||
} else if strings.Contains(colName, session.engine.QuoteStr()) {
|
||||
colName = strings.TrimSpace(strings.Replace(colName, session.engine.QuoteStr(), "", -1))
|
||||
// treat quote prefix, suffix and '`' as quotes
|
||||
quotes := append(strings.Split(session.engine.Quote(""), ""), "`")
|
||||
if strings.ContainsAny(colName, strings.Join(quotes, "")) {
|
||||
colName = strings.TrimSpace(eraseAny(colName, quotes...))
|
||||
} else {
|
||||
session.engine.logger.Debug("[cacheUpdate] cannot find column", tableName, colName)
|
||||
return ErrCacheFailed
|
||||
|
@ -221,19 +222,19 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
}
|
||||
}
|
||||
|
||||
//for update action to like "column = column + ?"
|
||||
// for update action to like "column = column + ?"
|
||||
incColumns := session.statement.getInc()
|
||||
for _, v := range incColumns {
|
||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" + ?")
|
||||
args = append(args, v.arg)
|
||||
}
|
||||
//for update action to like "column = column - ?"
|
||||
// for update action to like "column = column - ?"
|
||||
decColumns := session.statement.getDec()
|
||||
for _, v := range decColumns {
|
||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+session.engine.Quote(v.colName)+" - ?")
|
||||
args = append(args, v.arg)
|
||||
}
|
||||
//for update action to like "column = expression"
|
||||
// for update action to like "column = expression"
|
||||
exprColumns := session.statement.getExpr()
|
||||
for _, v := range exprColumns {
|
||||
colNames = append(colNames, session.engine.Quote(v.colName)+" = "+v.expr)
|
||||
|
@ -244,7 +245,9 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
}
|
||||
|
||||
var autoCond builder.Cond
|
||||
if !session.statement.noAutoCondition && len(condiBean) > 0 {
|
||||
if !session.statement.noAutoCondition {
|
||||
condBeanIsStruct := false
|
||||
if len(condiBean) > 0 {
|
||||
if c, ok := condiBean[0].(map[string]interface{}); ok {
|
||||
autoCond = builder.Eq(c)
|
||||
} else {
|
||||
|
@ -259,12 +262,26 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
condBeanIsStruct = true
|
||||
} else {
|
||||
return 0, ErrConditionType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !condBeanIsStruct && table != nil {
|
||||
if col := table.DeletedColumn(); col != nil && !session.statement.unscoped { // tag "deleted" is enabled
|
||||
autoCond1 := session.engine.CondDeleted(session.engine.Quote(col.Name))
|
||||
|
||||
if autoCond == nil {
|
||||
autoCond = autoCond1
|
||||
} else {
|
||||
autoCond = autoCond.And(autoCond1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
st := &session.statement
|
||||
|
||||
var sqlStr string
|
||||
|
@ -366,7 +383,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
|||
}
|
||||
|
||||
if cacher := session.engine.getCacher(tableName); cacher != nil && session.statement.UseCache {
|
||||
//session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||
// session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||
session.engine.logger.Debug("[cacheUpdate] clear table ", tableName)
|
||||
cacher.ClearIds(tableName)
|
||||
cacher.ClearBeans(tableName)
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
func TestUpdateMap(t *testing.T) {
|
||||
|
@ -1349,3 +1349,44 @@ func TestWhereCondErrorWhenUpdate(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
assert.EqualValues(t, ErrConditionType, err)
|
||||
}
|
||||
|
||||
func TestUpdateDeleted(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
|
||||
type UpdateDeletedStruct struct {
|
||||
Id int64
|
||||
Name string
|
||||
DeletedAt time.Time `xorm:"deleted"`
|
||||
}
|
||||
|
||||
assertSync(t, new(UpdateDeletedStruct))
|
||||
|
||||
var s = UpdateDeletedStruct{
|
||||
Name: "test",
|
||||
}
|
||||
cnt, err := testEngine.Insert(&s)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
cnt, err = testEngine.ID(s.Id).Delete(&UpdateDeletedStruct{})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
|
||||
cnt, err = testEngine.ID(s.Id).Update(&UpdateDeletedStruct{
|
||||
Name: "test1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 0, cnt)
|
||||
|
||||
cnt, err = testEngine.Table(&UpdateDeletedStruct{}).ID(s.Id).Update(map[string]interface{}{
|
||||
"name": "test1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 0, cnt)
|
||||
|
||||
cnt, err = testEngine.ID(s.Id).Unscoped().Update(&UpdateDeletedStruct{
|
||||
Name: "test1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, cnt)
|
||||
}
|
||||
|
|
46
statement.go
46
statement.go
|
@ -6,15 +6,13 @@ package xorm
|
|||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/builder"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/builder"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
// Statement save all the sql info for executing SQL
|
||||
|
@ -399,7 +397,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
|||
continue
|
||||
}
|
||||
} else {
|
||||
//TODO: how to handler?
|
||||
// TODO: how to handler?
|
||||
panic("not supported")
|
||||
}
|
||||
} else {
|
||||
|
@ -408,7 +406,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
|||
} else {
|
||||
// Blank struct could not be as update data
|
||||
if requiredField || !isStructZero(fieldValue) {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("mashal %v failed", fieldValue.Interface()))
|
||||
}
|
||||
|
@ -437,7 +435,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
|||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
bytes, err := json.Marshal(fieldValue.Interface())
|
||||
bytes, err := DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
continue
|
||||
|
@ -457,7 +455,7 @@ func (statement *Statement) buildUpdates(bean interface{},
|
|||
fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
val = fieldValue.Slice(0, 0).Interface()
|
||||
} else {
|
||||
bytes, err = json.Marshal(fieldValue.Interface())
|
||||
bytes, err = DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
engine.logger.Error(err)
|
||||
continue
|
||||
|
@ -580,21 +578,9 @@ func (statement *Statement) getExpr() map[string]exprParam {
|
|||
|
||||
func (statement *Statement) col2NewColsWithQuote(columns ...string) []string {
|
||||
newColumns := make([]string, 0)
|
||||
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||
for _, col := range columns {
|
||||
col = strings.Replace(col, "`", "", -1)
|
||||
col = strings.Replace(col, statement.Engine.QuoteStr(), "", -1)
|
||||
ccols := strings.Split(col, ",")
|
||||
for _, c := range ccols {
|
||||
fields := strings.Split(strings.TrimSpace(c), ".")
|
||||
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"))
|
||||
}
|
||||
}
|
||||
newColumns = append(newColumns, statement.Engine.Quote(eraseAny(col, quotes...)))
|
||||
}
|
||||
return newColumns
|
||||
}
|
||||
|
@ -765,7 +751,9 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
|||
return statement
|
||||
}
|
||||
tbs := strings.Split(tp.TableName(), ".")
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], statement.Engine.QuoteStr())
|
||||
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, ""))
|
||||
fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition)
|
||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||
case *builder.Builder:
|
||||
|
@ -775,7 +763,9 @@ func (statement *Statement) Join(joinOP string, tablename interface{}, condition
|
|||
return statement
|
||||
}
|
||||
tbs := strings.Split(tp.TableName(), ".")
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], statement.Engine.QuoteStr())
|
||||
quotes := append(strings.Split(statement.Engine.Quote(""), ""), "`")
|
||||
|
||||
var aliasName = strings.Trim(tbs[len(tbs)-1], strings.Join(quotes, ""))
|
||||
fmt.Fprintf(&buf, "(%s) %s ON %v", subSQL, aliasName, condition)
|
||||
statement.joinArgs = append(statement.joinArgs, subQueryArgs...)
|
||||
default:
|
||||
|
@ -1158,8 +1148,12 @@ func (statement *Statement) genSelectSQL(columnStr, condSQL string, needLimit, n
|
|||
if statement.Start != 0 || statement.LimitN != 0 {
|
||||
oldString := buf.String()
|
||||
buf.Reset()
|
||||
rawColStr := columnStr
|
||||
if rawColStr == "*" {
|
||||
rawColStr = "at.*"
|
||||
}
|
||||
fmt.Fprintf(&buf, "SELECT %v FROM (SELECT %v,ROWNUM RN FROM (%v) at WHERE ROWNUM <= %d) aat WHERE RN > %d",
|
||||
columnStr, columnStr, oldString, statement.Start+statement.LimitN, statement.Start)
|
||||
columnStr, rawColStr, oldString, statement.Start+statement.LimitN, statement.Start)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1243,7 +1237,7 @@ func (statement *Statement) convertUpdateSQL(sqlStr string) (string, string) {
|
|||
|
||||
var whereStr = sqls[1]
|
||||
|
||||
//TODO: for postgres only, if any other database?
|
||||
// TODO: for postgres only, if any other database?
|
||||
var paraStr string
|
||||
if statement.Engine.dialect.DBType() == core.POSTGRES {
|
||||
paraStr = "$"
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var colStrTests = []struct {
|
||||
|
@ -237,3 +237,12 @@ func TestUpdateIgnoreOnlyFromDBFields(t *testing.T) {
|
|||
testEngine.Update(record)
|
||||
assertGetRecord()
|
||||
}
|
||||
|
||||
func TestCol2NewColsWithQuote(t *testing.T) {
|
||||
cols := []string{"f1", "f2", "t3.f3"}
|
||||
|
||||
statement := createTestStatement()
|
||||
|
||||
quotedCols := statement.col2NewColsWithQuote(cols...)
|
||||
assert.EqualValues(t, []string{statement.Engine.Quote("f1"), statement.Engine.Quote("f2"), statement.Engine.Quote("t3.f3")}, quotedCols)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"fmt"
|
||||
"log/syslog"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var _ core.ILogger = &SyslogLogger{}
|
||||
|
|
22
tag.go
22
tag.go
|
@ -11,7 +11,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
type tagContext struct {
|
||||
|
@ -244,6 +244,7 @@ func SQLTypeTagHandler(ctx *tagContext) error {
|
|||
// ExtendsTagHandler describes extends tag handler
|
||||
func ExtendsTagHandler(ctx *tagContext) error {
|
||||
var fieldValue = ctx.fieldValue
|
||||
var isPtr = false
|
||||
switch fieldValue.Kind() {
|
||||
case reflect.Ptr:
|
||||
f := fieldValue.Type().Elem()
|
||||
|
@ -254,6 +255,7 @@ func ExtendsTagHandler(ctx *tagContext) error {
|
|||
fieldValue = reflect.New(f).Elem()
|
||||
}
|
||||
}
|
||||
isPtr = true
|
||||
fallthrough
|
||||
case reflect.Struct:
|
||||
parentTable, err := ctx.engine.mapType(fieldValue)
|
||||
|
@ -262,6 +264,24 @@ func ExtendsTagHandler(ctx *tagContext) error {
|
|||
}
|
||||
for _, col := range parentTable.Columns() {
|
||||
col.FieldName = fmt.Sprintf("%v.%v", ctx.col.FieldName, col.FieldName)
|
||||
|
||||
var tagPrefix = ctx.col.FieldName
|
||||
if len(ctx.params) > 0 {
|
||||
col.Nullable = isPtr
|
||||
tagPrefix = ctx.params[0]
|
||||
if col.IsPrimaryKey {
|
||||
col.Name = ctx.col.FieldName
|
||||
col.IsPrimaryKey = false
|
||||
} else {
|
||||
col.Name = fmt.Sprintf("%v%v", tagPrefix, col.Name)
|
||||
}
|
||||
}
|
||||
|
||||
if col.Nullable {
|
||||
col.IsAutoIncrement = false
|
||||
col.IsPrimaryKey = false
|
||||
}
|
||||
|
||||
ctx.table.AddColumn(col)
|
||||
for indexName, indexType := range col.Indexes {
|
||||
addIndex(indexName, ctx.table, col, indexType)
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -486,3 +486,123 @@ func TestExtends4(t *testing.T) {
|
|||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type Size struct {
|
||||
ID int64 `xorm:"int(4) 'id' pk autoincr"`
|
||||
Width float32 `json:"width" xorm:"float 'Width'"`
|
||||
Height float32 `json:"height" xorm:"float 'Height'"`
|
||||
}
|
||||
|
||||
type Book struct {
|
||||
ID int64 `xorm:"int(4) 'id' pk autoincr"`
|
||||
SizeOpen *Size `xorm:"extends('Open')"`
|
||||
SizeClosed *Size `xorm:"extends('Closed')"`
|
||||
Size *Size `xorm:"extends('')"`
|
||||
}
|
||||
|
||||
func TestExtends5(t *testing.T) {
|
||||
assert.NoError(t, prepareEngine())
|
||||
err := testEngine.DropTables(&Book{}, &Size{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = testEngine.CreateTables(&Size{}, &Book{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var sc = Size{Width: 0.2, Height: 0.4}
|
||||
var so = Size{Width: 0.2, Height: 0.8}
|
||||
var s = Size{Width: 0.15, Height: 1.5}
|
||||
var bk1 = Book{
|
||||
SizeOpen: &so,
|
||||
SizeClosed: &sc,
|
||||
Size: &s,
|
||||
}
|
||||
var bk2 = Book{
|
||||
SizeOpen: &so,
|
||||
}
|
||||
var bk3 = Book{
|
||||
SizeClosed: &sc,
|
||||
Size: &s,
|
||||
}
|
||||
var bk4 = Book{}
|
||||
var bk5 = Book{Size: &s}
|
||||
_, err = testEngine.Insert(&sc, &so, &s, &bk1, &bk2, &bk3, &bk4, &bk5)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var books = map[int64]Book{
|
||||
bk1.ID: bk1,
|
||||
bk2.ID: bk2,
|
||||
bk3.ID: bk3,
|
||||
bk4.ID: bk4,
|
||||
bk5.ID: bk5,
|
||||
}
|
||||
|
||||
session := testEngine.NewSession()
|
||||
defer session.Close()
|
||||
|
||||
var mapper = testEngine.GetTableMapper().Obj2Table
|
||||
var quote = testEngine.Quote
|
||||
bookTableName := quote(testEngine.TableName(mapper("Book"), true))
|
||||
sizeTableName := quote(testEngine.TableName(mapper("Size"), true))
|
||||
|
||||
list := make([]Book, 0)
|
||||
err = session.
|
||||
Select(fmt.Sprintf(
|
||||
"%s.%s, sc.%s AS %s, sc.%s AS %s, s.%s, s.%s",
|
||||
quote(bookTableName),
|
||||
quote("id"),
|
||||
quote("Width"),
|
||||
quote("ClosedWidth"),
|
||||
quote("Height"),
|
||||
quote("ClosedHeight"),
|
||||
quote("Width"),
|
||||
quote("Height"),
|
||||
)).
|
||||
Table(bookTableName).
|
||||
Join(
|
||||
"LEFT",
|
||||
sizeTableName+" AS `sc`",
|
||||
bookTableName+".`SizeClosed`=sc.`id`",
|
||||
).
|
||||
Join(
|
||||
"LEFT",
|
||||
sizeTableName+" AS `s`",
|
||||
bookTableName+".`Size`=s.`id`",
|
||||
).
|
||||
Find(&list)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, book := range list {
|
||||
if ok := assert.Equal(t, books[book.ID].SizeClosed.Width, book.SizeClosed.Width); !ok {
|
||||
t.Error("Not bounded size closed")
|
||||
panic("Not bounded size closed")
|
||||
}
|
||||
|
||||
if ok := assert.Equal(t, books[book.ID].SizeClosed.Height, book.SizeClosed.Height); !ok {
|
||||
t.Error("Not bounded size closed")
|
||||
panic("Not bounded size closed")
|
||||
}
|
||||
|
||||
if books[book.ID].Size != nil || book.Size != nil {
|
||||
if ok := assert.Equal(t, books[book.ID].Size.Width, book.Size.Width); !ok {
|
||||
t.Error("Not bounded size")
|
||||
panic("Not bounded size")
|
||||
}
|
||||
|
||||
if ok := assert.Equal(t, books[book.ID].Size.Height, book.Size.Height); !ok {
|
||||
t.Error("Not bounded size")
|
||||
panic("Not bounded size")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ package xorm
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
type UserCU struct {
|
||||
|
|
2
types.go
2
types.go
|
@ -7,7 +7,7 @@ package xorm
|
|||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
package xorm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -117,21 +116,21 @@ type ConvConfig struct {
|
|||
}
|
||||
|
||||
func (s *ConvConfig) FromDB(data []byte) error {
|
||||
return json.Unmarshal(data, s)
|
||||
return DefaultJSONHandler.Unmarshal(data, s)
|
||||
}
|
||||
|
||||
func (s *ConvConfig) ToDB() ([]byte, error) {
|
||||
return json.Marshal(s)
|
||||
return DefaultJSONHandler.Marshal(s)
|
||||
}
|
||||
|
||||
type SliceType []*ConvConfig
|
||||
|
||||
func (s *SliceType) FromDB(data []byte) error {
|
||||
return json.Unmarshal(data, s)
|
||||
return DefaultJSONHandler.Unmarshal(data, s)
|
||||
}
|
||||
|
||||
func (s *SliceType) ToDB() ([]byte, error) {
|
||||
return json.Marshal(s)
|
||||
return DefaultJSONHandler.Marshal(s)
|
||||
}
|
||||
|
||||
type ConvStruct struct {
|
||||
|
|
2
xorm.go
2
xorm.go
|
@ -15,7 +15,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
_ "github.com/denisenkom/go-mssqldb"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/go-xorm/core"
|
||||
"xorm.io/core"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
_ "github.com/ziutek/mymysql/godrv"
|
||||
|
|
Loading…
Reference in New Issue