Merge branch 'master' of https://github.com/go-xorm/xorm
Conflicts: session.go
This commit is contained in:
commit
7d79bd259b
142
README.md
142
README.md
|
@ -88,6 +88,148 @@ Or
|
||||||
|
|
||||||
* [GoWalker](http://gowalker.org/github.com/go-xorm/xorm)
|
* [GoWalker](http://gowalker.org/github.com/go-xorm/xorm)
|
||||||
|
|
||||||
|
# Quick Start
|
||||||
|
|
||||||
|
* Create Engine
|
||||||
|
|
||||||
|
```Go
|
||||||
|
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||||
|
```
|
||||||
|
|
||||||
|
* Define a struct and Sync2 table struct to database
|
||||||
|
|
||||||
|
```Go
|
||||||
|
type User struct {
|
||||||
|
Id int64
|
||||||
|
Name string
|
||||||
|
Salt string
|
||||||
|
Age int
|
||||||
|
Passwd string `xorm:"varchar(200)"`
|
||||||
|
Created time.Time `xorm:"created"`
|
||||||
|
Updated time.Time `xorm:"updated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := engine.Sync2(new(User))
|
||||||
|
```
|
||||||
|
|
||||||
|
* Query a SQL string, the returned results is []map[string][]byte
|
||||||
|
|
||||||
|
```Go
|
||||||
|
results, err := engine.Query("select * from user")
|
||||||
|
```
|
||||||
|
|
||||||
|
* Execute a SQL string, the returned results
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
|
||||||
|
```
|
||||||
|
|
||||||
|
* Insert one or multipe records to database
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Insert(&user)
|
||||||
|
// INSERT INTO struct () values ()
|
||||||
|
affected, err := engine.Insert(&user1, &user2)
|
||||||
|
// INSERT INTO struct1 () values ()
|
||||||
|
// INSERT INTO struct2 () values ()
|
||||||
|
affected, err := engine.Insert(&users)
|
||||||
|
// INSERT INTO struct () values (),(),()
|
||||||
|
affected, err := engine.Insert(&user1, &users)
|
||||||
|
// INSERT INTO struct1 () values ()
|
||||||
|
// INSERT INTO struct2 () values (),(),()
|
||||||
|
```
|
||||||
|
|
||||||
|
* Query one record from database
|
||||||
|
|
||||||
|
```Go
|
||||||
|
has, err := engine.Get(&user)
|
||||||
|
// SELECT * FROM user LIMIT 1
|
||||||
|
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
||||||
|
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||||
|
```
|
||||||
|
|
||||||
|
* Query multiple records from database, also you can use join and extends
|
||||||
|
|
||||||
|
```Go
|
||||||
|
var users []User
|
||||||
|
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
|
||||||
|
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
|
||||||
|
|
||||||
|
type Detail struct {
|
||||||
|
Id int64
|
||||||
|
UserId int64 `xorm:"index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserDetail struct {
|
||||||
|
User `xorm:"extends"`
|
||||||
|
Detail `xorm:"extends"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var users []UserDetail
|
||||||
|
err := engine.Table("user").Select("user.*, detail.*")
|
||||||
|
Join("INNER", "detail", "detail.user_id = user.id").
|
||||||
|
Where("user.name = ?", name).Limit(10, 0).
|
||||||
|
Find(&users)
|
||||||
|
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
|
||||||
|
```
|
||||||
|
|
||||||
|
* Query multiple records and record by record handle, there two methods Iterate and Rows
|
||||||
|
|
||||||
|
```Go
|
||||||
|
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
|
||||||
|
user := bean.(*User)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
// SELECT * FROM user
|
||||||
|
|
||||||
|
rows, err := engine.Rows(&User{Name:name})
|
||||||
|
// SELECT * FROM user
|
||||||
|
defer rows.Close()
|
||||||
|
bean := new(Struct)
|
||||||
|
for rows.Next() {
|
||||||
|
err = rows.Scan(bean)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Update one or more records, default will update non-empty and non-zero fields except to use Cols, AllCols and etc.
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Id(1).Update(&user)
|
||||||
|
// UPDATE user SET ... Where id = ?
|
||||||
|
|
||||||
|
affected, err := engine.Update(&user, &User{Name:name})
|
||||||
|
// UPDATE user SET ... Where name = ?
|
||||||
|
|
||||||
|
var ids = []int64{1, 2, 3}
|
||||||
|
affected, err := engine.In(ids).Update(&user)
|
||||||
|
// UPDATE user SET ... Where id IN (?, ?, ?)
|
||||||
|
|
||||||
|
// force update indicated columns by Cols
|
||||||
|
affected, err := engine.Id(1).Cols("age").Update(&User{Name:name, Age: 12})
|
||||||
|
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||||
|
|
||||||
|
// force NOT update indicated columns by Omit
|
||||||
|
affected, err := engine.Id(1).Omit("name").Update(&User{Name:name, Age: 12})
|
||||||
|
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||||
|
|
||||||
|
affected, err := engine.Id(1).AllCols().Update(&user)
|
||||||
|
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
|
||||||
|
```
|
||||||
|
|
||||||
|
* Delete one or more records, Delete MUST has conditon
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Where(...).Delete(&user)
|
||||||
|
// DELETE FROM user Where ...
|
||||||
|
```
|
||||||
|
|
||||||
|
* Count records
|
||||||
|
|
||||||
|
```Go
|
||||||
|
counts, err := engine.Count(&user)
|
||||||
|
// SELECT count(*) AS total FROM user
|
||||||
|
```
|
||||||
|
|
||||||
# Cases
|
# Cases
|
||||||
|
|
||||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||||
|
|
143
README_CN.md
143
README_CN.md
|
@ -84,8 +84,149 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||||
|
|
||||||
* [Godoc代码文档](http://godoc.org/github.com/go-xorm/xorm)
|
* [Godoc代码文档](http://godoc.org/github.com/go-xorm/xorm)
|
||||||
|
|
||||||
|
# 快速开始
|
||||||
|
|
||||||
## 案例
|
* 第一步创建引擎,driverName, dataSourceName和database/sql接口相同
|
||||||
|
|
||||||
|
```Go
|
||||||
|
engine, err := xorm.NewEngine(driverName, dataSourceName)
|
||||||
|
```
|
||||||
|
|
||||||
|
* 定义一个和表同步的结构体,并且自动同步结构体到数据库
|
||||||
|
|
||||||
|
```Go
|
||||||
|
type User struct {
|
||||||
|
Id int64
|
||||||
|
Name string
|
||||||
|
Salt string
|
||||||
|
Age int
|
||||||
|
Passwd string `xorm:"varchar(200)"`
|
||||||
|
Created time.Time `xorm:"created"`
|
||||||
|
Updated time.Time `xorm:"updated"`
|
||||||
|
}
|
||||||
|
|
||||||
|
err := engine.Sync2(new(User))
|
||||||
|
```
|
||||||
|
|
||||||
|
* 最原始的也支持SQL语句查询,返回的结果类型为 []map[string][]byte
|
||||||
|
|
||||||
|
```Go
|
||||||
|
results, err := engine.Query("select * from user")
|
||||||
|
```
|
||||||
|
|
||||||
|
* 执行一个SQL语句
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Exec("update user set age = ? where name = ?", age, name)
|
||||||
|
```
|
||||||
|
|
||||||
|
* 插入一条或者多条记录
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Insert(&user)
|
||||||
|
// INSERT INTO struct () values ()
|
||||||
|
affected, err := engine.Insert(&user1, &user2)
|
||||||
|
// INSERT INTO struct1 () values ()
|
||||||
|
// INSERT INTO struct2 () values ()
|
||||||
|
affected, err := engine.Insert(&users)
|
||||||
|
// INSERT INTO struct () values (),(),()
|
||||||
|
affected, err := engine.Insert(&user1, &users)
|
||||||
|
// INSERT INTO struct1 () values ()
|
||||||
|
// INSERT INTO struct2 () values (),(),()
|
||||||
|
```
|
||||||
|
|
||||||
|
* 查询单条记录
|
||||||
|
|
||||||
|
```Go
|
||||||
|
has, err := engine.Get(&user)
|
||||||
|
// SELECT * FROM user LIMIT 1
|
||||||
|
has, err := engine.Where("name = ?", name).Desc("id").Get(&user)
|
||||||
|
// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1
|
||||||
|
```
|
||||||
|
|
||||||
|
* 查询多条记录,当然可以使用Join和extends来组合使用
|
||||||
|
|
||||||
|
```Go
|
||||||
|
var users []User
|
||||||
|
err := engine.Where("name = ?", name).And("age > 10").Limit(10, 0).Find(&users)
|
||||||
|
// SELECT * FROM user WHERE name = ? AND age > 10 limit 0 offset 10
|
||||||
|
|
||||||
|
type Detail struct {
|
||||||
|
Id int64
|
||||||
|
UserId int64 `xorm:"index"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserDetail struct {
|
||||||
|
User `xorm:"extends"`
|
||||||
|
Detail `xorm:"extends"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var users []UserDetail
|
||||||
|
err := engine.Table("user").Select("user.*, detail.*")
|
||||||
|
Join("INNER", "detail", "detail.user_id = user.id").
|
||||||
|
Where("user.name = ?", name).Limit(10, 0).
|
||||||
|
Find(&users)
|
||||||
|
// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 0 offset 10
|
||||||
|
```
|
||||||
|
|
||||||
|
* 根据条件遍历数据库,可以有两种方式: Iterate and Rows
|
||||||
|
|
||||||
|
```Go
|
||||||
|
err := engine.Iterate(&User{Name:name}, func(idx int, bean interface{}) error {
|
||||||
|
user := bean.(*User)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
// SELECT * FROM user
|
||||||
|
|
||||||
|
rows, err := engine.Rows(&User{Name:name})
|
||||||
|
// SELECT * FROM user
|
||||||
|
defer rows.Close()
|
||||||
|
bean := new(Struct)
|
||||||
|
for rows.Next() {
|
||||||
|
err = rows.Scan(bean)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* 更新数据,除非使用Cols,AllCols函数指明,默认只更新非空和非0的字段
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Id(1).Update(&user)
|
||||||
|
// UPDATE user SET ... Where id = ?
|
||||||
|
|
||||||
|
affected, err := engine.Update(&user, &User{Name:name})
|
||||||
|
// UPDATE user SET ... Where name = ?
|
||||||
|
|
||||||
|
var ids = []int64{1, 2, 3}
|
||||||
|
affected, err := engine.In(ids).Update(&user)
|
||||||
|
// UPDATE user SET ... Where id IN (?, ?, ?)
|
||||||
|
|
||||||
|
// force update indicated columns by Cols
|
||||||
|
affected, err := engine.Id(1).Cols("age").Update(&User{Name:name, Age: 12})
|
||||||
|
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||||
|
|
||||||
|
// force NOT update indicated columns by Omit
|
||||||
|
affected, err := engine.Id(1).Omit("name").Update(&User{Name:name, Age: 12})
|
||||||
|
// UPDATE user SET age = ?, updated=? Where id = ?
|
||||||
|
|
||||||
|
affected, err := engine.Id(1).AllCols().Update(&user)
|
||||||
|
// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?
|
||||||
|
```
|
||||||
|
|
||||||
|
* 删除记录,需要注意,删除必须至少有一个条件,否则会报错。要清空数据库可以用EmptyTable
|
||||||
|
|
||||||
|
```Go
|
||||||
|
affected, err := engine.Where(...).Delete(&user)
|
||||||
|
// DELETE FROM user Where ...
|
||||||
|
```
|
||||||
|
|
||||||
|
* 获取记录条数
|
||||||
|
|
||||||
|
```Go
|
||||||
|
counts, err := engine.Count(&user)
|
||||||
|
// SELECT count(*) AS total FROM user
|
||||||
|
```
|
||||||
|
|
||||||
|
# 案例
|
||||||
|
|
||||||
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)
|
||||||
|
|
||||||
|
|
28
engine.go
28
engine.go
|
@ -320,6 +320,12 @@ func (engine *Engine) NoAutoTime() *Session {
|
||||||
return session.NoAutoTime()
|
return session.NoAutoTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (engine *Engine) NoAutoCondition(no ...bool) *Session {
|
||||||
|
session := engine.NewSession()
|
||||||
|
session.IsAutoClose = true
|
||||||
|
return session.NoAutoCondition(no...)
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve all tables, columns, indexes' informations from database.
|
// Retrieve all tables, columns, indexes' informations from database.
|
||||||
func (engine *Engine) DBMetas() ([]*core.Table, error) {
|
func (engine *Engine) DBMetas() ([]*core.Table, error) {
|
||||||
tables, err := engine.dialect.GetTables()
|
tables, err := engine.dialect.GetTables()
|
||||||
|
@ -377,13 +383,25 @@ func (engine *Engine) DumpAll(w io.Writer) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, table := range tables {
|
_, err = io.WriteString(w, fmt.Sprintf("/*Generated by xorm v%s %s*/\n\n",
|
||||||
_, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", table.StoreEngine, "")+"\n\n")
|
Version, time.Now().In(engine.TZLocation).Format("2006-01-02 15:04:05")))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, table := range tables {
|
||||||
|
if i > 0 {
|
||||||
|
_, err = io.WriteString(w, "\n")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err = io.WriteString(w, engine.dialect.CreateTableSql(table, "", table.StoreEngine, "")+";\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, index := range table.Indexes {
|
for _, index := range table.Indexes {
|
||||||
_, err = io.WriteString(w, engine.dialect.CreateIndexSql(table.Name, index)+"\n\n")
|
_, err = io.WriteString(w, engine.dialect.CreateIndexSql(table.Name, index)+";\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -443,7 +461,7 @@ func (engine *Engine) DumpAll(w io.Writer) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, err = io.WriteString(w, temp[2:]+");\n\n")
|
_, err = io.WriteString(w, temp[2:]+");\n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -747,7 +765,7 @@ func (engine *Engine) mapType(v reflect.Value) *core.Table {
|
||||||
if ormTagStr != "" {
|
if ormTagStr != "" {
|
||||||
col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false,
|
col = &core.Column{FieldName: t.Field(i).Name, Nullable: true, IsPrimaryKey: false,
|
||||||
IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]bool)}
|
IsAutoIncrement: false, MapType: core.TWOSIDES, Indexes: make(map[string]bool)}
|
||||||
tags := strings.Split(ormTagStr, " ")
|
tags := splitTag(ormTagStr)
|
||||||
|
|
||||||
if len(tags) > 0 {
|
if len(tags) > 0 {
|
||||||
if tags[0] == "-" {
|
if tags[0] == "-" {
|
||||||
|
|
49
helpers.go
49
helpers.go
|
@ -15,6 +15,30 @@ import (
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func splitTag(tag string) (tags []string) {
|
||||||
|
tag = strings.TrimSpace(tag)
|
||||||
|
var hasQuote = false
|
||||||
|
var lastIdx = 0
|
||||||
|
for i, t := range tag {
|
||||||
|
if t == '\'' {
|
||||||
|
hasQuote = !hasQuote
|
||||||
|
} else if t == ' ' {
|
||||||
|
if lastIdx < i && !hasQuote {
|
||||||
|
tags = append(tags, strings.TrimSpace(tag[lastIdx:i]))
|
||||||
|
lastIdx = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if lastIdx < len(tag) {
|
||||||
|
tags = append(tags, strings.TrimSpace(tag[lastIdx:len(tag)]))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type zeroable interface {
|
||||||
|
IsZero() bool
|
||||||
|
}
|
||||||
|
|
||||||
func isZero(k interface{}) bool {
|
func isZero(k interface{}) bool {
|
||||||
switch k.(type) {
|
switch k.(type) {
|
||||||
case int:
|
case int:
|
||||||
|
@ -45,12 +69,33 @@ func isZero(k interface{}) bool {
|
||||||
return k.(bool) == false
|
return k.(bool) == false
|
||||||
case string:
|
case string:
|
||||||
return k.(string) == ""
|
return k.(string) == ""
|
||||||
case time.Time:
|
case zeroable:
|
||||||
return k.(time.Time).IsZero()
|
return k.(zeroable).IsZero()
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func int64ToInt(id int64, k reflect.Kind) interface{} {
|
||||||
|
var v interface{} = id
|
||||||
|
switch k {
|
||||||
|
case reflect.Int16:
|
||||||
|
v = int16(id)
|
||||||
|
case reflect.Int32:
|
||||||
|
v = int32(id)
|
||||||
|
case reflect.Int:
|
||||||
|
v = int(id)
|
||||||
|
case reflect.Uint16:
|
||||||
|
v = uint16(id)
|
||||||
|
case reflect.Uint32:
|
||||||
|
v = uint32(id)
|
||||||
|
case reflect.Uint64:
|
||||||
|
v = uint64(id)
|
||||||
|
case reflect.Uint:
|
||||||
|
v = uint(id)
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
func isPKZero(pk core.PK) bool {
|
func isPKZero(pk core.PK) bool {
|
||||||
for _, k := range pk {
|
for _, k := range pk {
|
||||||
if isZero(k) {
|
if isZero(k) {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package xorm
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSplitTag(t *testing.T) {
|
||||||
|
var cases = []struct {
|
||||||
|
tag string
|
||||||
|
tags []string
|
||||||
|
}{
|
||||||
|
{"not null default '2000-01-01 00:00:00' TIMESTAMP", []string{"not", "null", "default", "'2000-01-01 00:00:00'", "TIMESTAMP"}},
|
||||||
|
{"TEXT", []string{"TEXT"}},
|
||||||
|
{"default('2000-01-01 00:00:00')", []string{"default('2000-01-01 00:00:00')"}},
|
||||||
|
{"json binary", []string{"json", "binary"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, kase := range cases {
|
||||||
|
tags := splitTag(kase.tag)
|
||||||
|
if !sliceEq(tags, kase.tags) {
|
||||||
|
t.Fatalf("[%d]%v is not equal [%d]%v", len(tags), tags, len(kase.tags), kase.tags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ func parseURL(connstr string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Scheme != "postgres" {
|
if u.Scheme != "postgresql" && u.Scheme != "postgres" {
|
||||||
return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
|
return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ func (p *pqDriver) Parse(driverName, dataSourceName string) (*core.Uri, error) {
|
||||||
db := &core.Uri{DbType: core.POSTGRES}
|
db := &core.Uri{DbType: core.POSTGRES}
|
||||||
o := make(values)
|
o := make(values)
|
||||||
var err error
|
var err error
|
||||||
if strings.HasPrefix(dataSourceName, "postgres://") {
|
if strings.HasPrefix(dataSourceName, "postgresql://") || strings.HasPrefix(dataSourceName, "postgres://") {
|
||||||
dataSourceName, err = parseURL(dataSourceName)
|
dataSourceName, err = parseURL(dataSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
520
session.go
520
session.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2015 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
|
package xorm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -40,6 +44,7 @@ type Session struct {
|
||||||
beforeClosures []func(interface{})
|
beforeClosures []func(interface{})
|
||||||
afterClosures []func(interface{})
|
afterClosures []func(interface{})
|
||||||
|
|
||||||
|
prepareStmt bool
|
||||||
stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr))
|
stmtCache map[uint32]*core.Stmt //key: hash.Hash32 of (queryStr, len(queryStr))
|
||||||
cascadeDeep int
|
cascadeDeep int
|
||||||
|
|
||||||
|
@ -50,12 +55,13 @@ type Session struct {
|
||||||
|
|
||||||
// Method Init reset the session as the init status.
|
// Method Init reset the session as the init status.
|
||||||
func (session *Session) Init() {
|
func (session *Session) Init() {
|
||||||
session.Statement = Statement{Engine: session.Engine}
|
|
||||||
session.Statement.Init()
|
session.Statement.Init()
|
||||||
|
session.Statement.Engine = session.Engine
|
||||||
session.IsAutoCommit = true
|
session.IsAutoCommit = true
|
||||||
session.IsCommitedOrRollbacked = false
|
session.IsCommitedOrRollbacked = false
|
||||||
session.IsAutoClose = false
|
session.IsAutoClose = false
|
||||||
session.AutoResetStatement = true
|
session.AutoResetStatement = true
|
||||||
|
session.prepareStmt = false
|
||||||
|
|
||||||
// !nashtsai! is lazy init better?
|
// !nashtsai! is lazy init better?
|
||||||
session.afterInsertBeans = make(map[interface{}]*[]func(interface{}), 0)
|
session.afterInsertBeans = make(map[interface{}]*[]func(interface{}), 0)
|
||||||
|
@ -75,11 +81,15 @@ func (session *Session) Close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.db != nil {
|
if session.db != nil {
|
||||||
//session.Engine.Pool.ReleaseDB(session.Engine, session.Db)
|
// When Close be called, if session is a transaction and do not call
|
||||||
session.db = nil
|
// Commit or Rollback, then call Rollback.
|
||||||
|
if session.Tx != nil && !session.IsCommitedOrRollbacked {
|
||||||
|
session.Rollback()
|
||||||
|
}
|
||||||
session.Tx = nil
|
session.Tx = nil
|
||||||
session.stmtCache = nil
|
session.stmtCache = nil
|
||||||
session.Init()
|
session.Init()
|
||||||
|
session.db = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +99,12 @@ func (session *Session) resetStatement() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
func (session *Session) Prepare() *Session {
|
||||||
|
session.prepareStmt = true
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
// Method Sql provides raw sql input parameter. When you have a complex SQL statement
|
// Method 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.
|
// and cannot use Where, Id, In and etc. Methods to describe, you can use Sql.
|
||||||
func (session *Session) Sql(querystring string, args ...interface{}) *Session {
|
func (session *Session) Sql(querystring string, args ...interface{}) *Session {
|
||||||
|
@ -172,6 +188,12 @@ func (session *Session) SetExpr(column string, expression string) *Session {
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Method Cols provides some columns to special
|
||||||
|
func (session *Session) Select(str string) *Session {
|
||||||
|
session.Statement.Select(str)
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
// Method Cols provides some columns to special
|
// Method Cols provides some columns to special
|
||||||
func (session *Session) Cols(columns ...string) *Session {
|
func (session *Session) Cols(columns ...string) *Session {
|
||||||
session.Statement.Cols(columns...)
|
session.Statement.Cols(columns...)
|
||||||
|
@ -223,6 +245,12 @@ func (session *Session) Omit(columns ...string) *Session {
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set null when column is zero-value and nullable for update
|
||||||
|
func (session *Session) Nullable(columns ...string) *Session {
|
||||||
|
session.Statement.Nullable(columns...)
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
// Method NoAutoTime means do not automatically give created field and updated field
|
// Method NoAutoTime means do not automatically give created field and updated field
|
||||||
// the current time on the current session temporarily
|
// the current time on the current session temporarily
|
||||||
func (session *Session) NoAutoTime() *Session {
|
func (session *Session) NoAutoTime() *Session {
|
||||||
|
@ -230,6 +258,11 @@ func (session *Session) NoAutoTime() *Session {
|
||||||
return session
|
return session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (session *Session) NoAutoCondition(no ...bool) *Session {
|
||||||
|
session.Statement.NoAutoCondition(no...)
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
// Method Limit provide limit and offset query condition
|
// Method Limit provide limit and offset query condition
|
||||||
func (session *Session) Limit(limit int, start ...int) *Session {
|
func (session *Session) Limit(limit int, start ...int) *Session {
|
||||||
session.Statement.Limit(limit, start...)
|
session.Statement.Limit(limit, start...)
|
||||||
|
@ -439,17 +472,20 @@ func (session *Session) scanMapIntoStruct(obj interface{}, objMap map[string][]b
|
||||||
|
|
||||||
//Execute sql
|
//Execute sql
|
||||||
func (session *Session) innerExec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
func (session *Session) innerExec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
||||||
|
if session.prepareStmt {
|
||||||
stmt, err := session.doPrepare(sqlStr)
|
stmt, err := session.doPrepare(sqlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
//defer stmt.Close()
|
|
||||||
|
|
||||||
res, err := stmt.Exec(args...)
|
res, err := stmt.Exec(args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return session.DB().Exec(sqlStr, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
func (session *Session) exec(sqlStr string, args ...interface{}) (sql.Result, error) {
|
||||||
|
@ -633,8 +669,6 @@ func (statement *Statement) convertIdSql(sqlStr string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
func (session *Session) canCache() bool {
|
func (session *Session) canCache() bool {
|
||||||
if session.Statement.RefTable == nil ||
|
if session.Statement.RefTable == nil ||
|
||||||
session.Statement.JoinStr != "" ||
|
session.Statement.JoinStr != "" ||
|
||||||
|
@ -646,12 +680,9 @@ func (session *Session) canCache() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
>>>>>>> refs/remotes/go-xorm/master
|
|
||||||
func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) {
|
func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interface{}) (has bool, err error) {
|
||||||
// if has no reftable, then don't use cache currently
|
// if has no reftable, then don't use cache currently
|
||||||
if session.Statement.RefTable == nil ||
|
if !session.canCache() {
|
||||||
session.Statement.JoinStr != "" ||
|
|
||||||
session.Statement.RawSQL != "" {
|
|
||||||
return false, ErrCacheFailed
|
return false, ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -749,11 +780,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) {
|
func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr interface{}, args ...interface{}) (err error) {
|
||||||
<<<<<<< HEAD
|
|
||||||
if session.Statement.RefTable == nil ||
|
|
||||||
=======
|
|
||||||
if !session.canCache() ||
|
if !session.canCache() ||
|
||||||
>>>>>>> refs/remotes/go-xorm/master
|
|
||||||
indexNoCase(sqlStr, "having") != -1 ||
|
indexNoCase(sqlStr, "having") != -1 ||
|
||||||
indexNoCase(sqlStr, "group by") != -1 {
|
indexNoCase(sqlStr, "group by") != -1 {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
|
@ -897,7 +924,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
}
|
}
|
||||||
|
|
||||||
temps[ididxes[sid]] = bean
|
temps[ididxes[sid]] = bean
|
||||||
session.Engine.LogDebug("[cacheFind] cache bean:", tableName, id, bean)
|
session.Engine.LogDebug("[cacheFind] cache bean:", tableName, id, bean, temps)
|
||||||
cacher.PutBean(tableName, sid, bean)
|
cacher.PutBean(tableName, sid, bean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -905,7 +932,7 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
for j := 0; j < len(temps); j++ {
|
for j := 0; j < len(temps); j++ {
|
||||||
bean := temps[j]
|
bean := temps[j]
|
||||||
if bean == nil {
|
if bean == nil {
|
||||||
session.Engine.LogWarn("[cacheFind] cache no hit:", tableName, ides[j])
|
session.Engine.LogWarn("[cacheFind] cache no hit:", tableName, ids[j], temps)
|
||||||
// return errors.New("cache error") // !nashtsai! no need to return error, but continue instead
|
// return errors.New("cache error") // !nashtsai! no need to return error, but continue instead
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -1030,12 +1057,16 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
||||||
var err error
|
var err error
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
session.queryPreprocess(&sqlStr, args...)
|
||||||
if session.IsAutoCommit {
|
if session.IsAutoCommit {
|
||||||
stmt, err := session.doPrepare(sqlStr)
|
if session.prepareStmt {
|
||||||
if err != nil {
|
stmt, errPrepare := session.doPrepare(sqlStr)
|
||||||
return false, err
|
if errPrepare != nil {
|
||||||
|
return false, errPrepare
|
||||||
}
|
}
|
||||||
// defer stmt.Close() // !nashtsai! don't close due to stmt is cached and bounded to this session
|
// defer stmt.Close() // !nashtsai! don't close due to stmt is cached and bounded to this session
|
||||||
rawRows, err = stmt.Query(args...)
|
rawRows, err = stmt.Query(args...)
|
||||||
|
} else {
|
||||||
|
rawRows, err = session.DB().Query(sqlStr, args...)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rawRows, err = session.Tx.Query(sqlStr, args...)
|
rawRows, err = session.Tx.Query(sqlStr, args...)
|
||||||
}
|
}
|
||||||
|
@ -1157,161 +1188,6 @@ func Atot(s string, tp reflect.Type) (interface{}, error) {
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) FindMap(rowsSlicePtr interface{}, condiBean ...interface{}) error {
|
|
||||||
defer session.resetStatement()
|
|
||||||
if session.IsAutoClose {
|
|
||||||
defer session.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
|
||||||
if sliceValue.Kind() != reflect.Slice && sliceValue.Kind() != reflect.Map {
|
|
||||||
return errors.New("needs a pointer to a slice or a map")
|
|
||||||
}
|
|
||||||
|
|
||||||
sliceElementType := sliceValue.Type().Elem()
|
|
||||||
//fmt.Println("sliceValue.Kind()", sliceValue.Kind(), sliceElementType)
|
|
||||||
|
|
||||||
//fmt.Println("sliceValue.Kind()")
|
|
||||||
/*
|
|
||||||
if len(condiBean) > 0 {
|
|
||||||
colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true,
|
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
|
||||||
session.Statement.unscoped, session.Statement.mustColumnMap)
|
|
||||||
session.Statement.ConditionStr = strings.Join(colNames, " AND ")
|
|
||||||
session.Statement.BeanArgs = args
|
|
||||||
} else {
|
|
||||||
// !oinume! Add "<col> IS NULL" to WHERE whatever condiBean is given.
|
|
||||||
// See https://github.com/go-xorm/xorm/issues/179
|
|
||||||
if col := table.DeletedColumn(); col != nil && !session.Statement.unscoped { // tag "deleted" is enabled
|
|
||||||
session.Statement.ConditionStr = fmt.Sprintf("(%v IS NULL or %v = '0001-01-01 00:00:00') ",
|
|
||||||
session.Engine.Quote(col.Name), session.Engine.Quote(col.Name))
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
//fmt.Println("sliceValue.Kind()")
|
|
||||||
var sqlStr string
|
|
||||||
var args []interface{}
|
|
||||||
if session.Statement.RawSQL == "" {
|
|
||||||
var columnStr string = session.Statement.ColumnStr
|
|
||||||
if session.Statement.JoinStr == "" {
|
|
||||||
if columnStr == "" {
|
|
||||||
if session.Statement.GroupByStr != "" {
|
|
||||||
columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1))
|
|
||||||
} else {
|
|
||||||
columnStr = session.Statement.genColumnStr()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if columnStr == "" {
|
|
||||||
if session.Statement.GroupByStr != "" {
|
|
||||||
columnStr = session.Statement.Engine.Quote(strings.Replace(session.Statement.GroupByStr, ",", session.Engine.Quote(","), -1))
|
|
||||||
} else {
|
|
||||||
columnStr = "*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
session.Statement.attachInSql()
|
|
||||||
|
|
||||||
sqlStr = session.Statement.genSelectSql(columnStr)
|
|
||||||
args = append(session.Statement.Params, session.Statement.BeanArgs...)
|
|
||||||
// for mssql and use limit
|
|
||||||
qs := strings.Count(sqlStr, "?")
|
|
||||||
if len(args)*2 == qs {
|
|
||||||
args = append(args, args...)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sqlStr = session.Statement.RawSQL
|
|
||||||
args = session.Statement.RawParams
|
|
||||||
}
|
|
||||||
//fmt.Println("sliceValue.Kind()")
|
|
||||||
// var err error
|
|
||||||
/*
|
|
||||||
if session.Statement.JoinStr == "" {
|
|
||||||
if cacher := session.Engine.getCacher2(table); cacher != nil &&
|
|
||||||
session.Statement.UseCache &&
|
|
||||||
!session.Statement.IsDistinct &&
|
|
||||||
!session.Statement.unscoped {
|
|
||||||
err = session.cacheFind(sliceElementType, sqlStr, rowsSlicePtr, args...)
|
|
||||||
if err != ErrCacheFailed {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = nil // !nashtsai! reset err to nil for ErrCacheFailed
|
|
||||||
session.Engine.LogWarn("Cache Find Failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
//fmt.Println("sliceValue.Kind()", sliceValue.Kind())
|
|
||||||
if sliceValue.Kind() != reflect.Map {
|
|
||||||
fmt.Println("sliceValue.Type()", sliceValue.Type(), reflect.TypeOf(make(map[string]interface{})).Name())
|
|
||||||
|
|
||||||
if sliceElementType == reflect.TypeOf(make(map[string]interface{})) {
|
|
||||||
//fmt.Println("sliceValue.Type()OK")
|
|
||||||
resultsSlice, err := session.queryX(sqlStr, args...)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("sliceValue.Type()err", err.Error())
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, results := range resultsSlice {
|
|
||||||
//fmt.Println("sliceValue.Type()OK", results)
|
|
||||||
lRec := make(map[string]interface{})
|
|
||||||
for key, val := range results {
|
|
||||||
lRec[key] = val
|
|
||||||
/*
|
|
||||||
lValPr := reflect.Indirect(reflect.ValueOf(val))
|
|
||||||
lVal := reflect.ValueOf(lValPr.Interface())
|
|
||||||
fmt.Println(key, lVal.Type())
|
|
||||||
switch reflect.TypeOf(val).Kind() {
|
|
||||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
||||||
//str = strconv.FormatInt(lVal.Int(), 10)
|
|
||||||
lRec[key] = lVal.Int()
|
|
||||||
fmt.Println(key, lVal.Int())
|
|
||||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
||||||
//str = strconv.FormatUint(lVal.Uint(), 10)
|
|
||||||
lRec[key] = lVal.Uint()
|
|
||||||
fmt.Println(key, lVal.Uint())
|
|
||||||
case reflect.Float32, reflect.Float64:
|
|
||||||
//str = strconv.FormatFloat(lVal.Float(), 'f', -1, 64)
|
|
||||||
lRec[key] = lVal.Float()
|
|
||||||
fmt.Println(key, lVal.Float())
|
|
||||||
case reflect.Slice:
|
|
||||||
|
|
||||||
fmt.Println(key, lVal)
|
|
||||||
/*if lVal.Elem().Kind() == reflect.Uint8 {
|
|
||||||
// result[key] = string(reflect.ValueOf(val).Interface().([]byte))
|
|
||||||
// fmt.Println(key, aa.Kind())
|
|
||||||
break
|
|
||||||
}*/
|
|
||||||
/*
|
|
||||||
case reflect.String:
|
|
||||||
//str = lVal.String()
|
|
||||||
lRec[key] = lVal.String()
|
|
||||||
fmt.Println(key, lVal.String())
|
|
||||||
//时间类型
|
|
||||||
case reflect.Struct:
|
|
||||||
if val, ok := lVal.Interface().(time.Time); ok {
|
|
||||||
lRec[key] = val //lVal.Interface().(time.Time)
|
|
||||||
fmt.Println(key, val, lVal.Interface().(time.Time))
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Println(key, lVal.Kind())
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(lRec))))
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
fmt.Println("sliceValue.Index(0).Type() == reflect.TypeOf(make(map[string]interface{}))")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println("sliceValue.Kind() != reflect.Map")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find retrieve records from table, condiBeans's non-empty fields
|
// Find retrieve records from table, condiBeans's non-empty fields
|
||||||
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
// are conditions. beans could be []Struct, []*Struct, map[int64]Struct
|
||||||
// map[int64]*Struct
|
// map[int64]*Struct
|
||||||
|
@ -1327,7 +1203,6 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
sliceElementType := sliceValue.Type().Elem()
|
sliceElementType := sliceValue.Type().Elem()
|
||||||
|
|
||||||
var table *core.Table
|
var table *core.Table
|
||||||
if session.Statement.RefTable == nil {
|
if session.Statement.RefTable == nil {
|
||||||
if sliceElementType.Kind() == reflect.Ptr {
|
if sliceElementType.Kind() == reflect.Ptr {
|
||||||
|
@ -1335,7 +1210,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
pv := reflect.New(sliceElementType.Elem())
|
pv := reflect.New(sliceElementType.Elem())
|
||||||
table = session.Engine.autoMapType(pv.Elem())
|
table = session.Engine.autoMapType(pv.Elem())
|
||||||
} else {
|
} else {
|
||||||
|
return errors.New("slice type")
|
||||||
}
|
}
|
||||||
} else if sliceElementType.Kind() == reflect.Struct {
|
} else if sliceElementType.Kind() == reflect.Struct {
|
||||||
pv := reflect.New(sliceElementType)
|
pv := reflect.New(sliceElementType)
|
||||||
|
@ -1347,21 +1222,13 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
} else {
|
} else {
|
||||||
table = session.Statement.RefTable
|
table = session.Statement.RefTable
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
fmt.Println("sliceValue.Kind()")
|
|
||||||
if len(condiBean) > 0 {
|
|
||||||
colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true,
|
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
|
||||||
session.Statement.unscoped, session.Statement.mustColumnMap)
|
|
||||||
=======
|
|
||||||
|
|
||||||
var addedTableName = (len(session.Statement.JoinStr) > 0)
|
var addedTableName = (len(session.Statement.JoinStr) > 0)
|
||||||
if len(condiBean) > 0 {
|
if !session.Statement.noAutoCondition && len(condiBean) > 0 {
|
||||||
colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true,
|
colNames, args := buildConditions(session.Engine, table, condiBean[0], true, true,
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
session.Statement.unscoped, session.Statement.mustColumnMap,
|
session.Statement.unscoped, session.Statement.mustColumnMap,
|
||||||
session.Statement.TableName(), addedTableName)
|
session.Statement.TableName(), addedTableName)
|
||||||
>>>>>>> refs/remotes/go-xorm/master
|
|
||||||
session.Statement.ConditionStr = strings.Join(colNames, " AND ")
|
session.Statement.ConditionStr = strings.Join(colNames, " AND ")
|
||||||
session.Statement.BeanArgs = args
|
session.Statement.BeanArgs = args
|
||||||
} else {
|
} else {
|
||||||
|
@ -1376,11 +1243,14 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
colName, colName)
|
colName, colName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println("sliceValue.Kind()")
|
|
||||||
var sqlStr string
|
var sqlStr string
|
||||||
var args []interface{}
|
var args []interface{}
|
||||||
if session.Statement.RawSQL == "" {
|
if session.Statement.RawSQL == "" {
|
||||||
var columnStr string = session.Statement.ColumnStr
|
var columnStr string = session.Statement.ColumnStr
|
||||||
|
if len(session.Statement.selectStr) > 0 {
|
||||||
|
columnStr = session.Statement.selectStr
|
||||||
|
} else {
|
||||||
if session.Statement.JoinStr == "" {
|
if session.Statement.JoinStr == "" {
|
||||||
if columnStr == "" {
|
if columnStr == "" {
|
||||||
if session.Statement.GroupByStr != "" {
|
if session.Statement.GroupByStr != "" {
|
||||||
|
@ -1398,6 +1268,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
session.Statement.attachInSql()
|
session.Statement.attachInSql()
|
||||||
|
|
||||||
|
@ -1412,7 +1283,7 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
sqlStr = session.Statement.RawSQL
|
sqlStr = session.Statement.RawSQL
|
||||||
args = session.Statement.RawParams
|
args = session.Statement.RawParams
|
||||||
}
|
}
|
||||||
fmt.Println("sliceValue.Kind()")
|
|
||||||
var err error
|
var err error
|
||||||
if session.Statement.JoinStr == "" {
|
if session.Statement.JoinStr == "" {
|
||||||
if cacher := session.Engine.getCacher2(table); cacher != nil &&
|
if cacher := session.Engine.getCacher2(table); cacher != nil &&
|
||||||
|
@ -1428,20 +1299,22 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("sliceValue.Kind()", sliceValue.Kind())
|
|
||||||
if sliceValue.Kind() != reflect.Map {
|
if sliceValue.Kind() != reflect.Map {
|
||||||
|
|
||||||
var rawRows *core.Rows
|
var rawRows *core.Rows
|
||||||
var stmt *core.Stmt
|
var stmt *core.Stmt
|
||||||
|
|
||||||
session.queryPreprocess(&sqlStr, args...)
|
session.queryPreprocess(&sqlStr, args...)
|
||||||
|
|
||||||
if session.IsAutoCommit {
|
if session.IsAutoCommit {
|
||||||
|
if session.prepareStmt {
|
||||||
stmt, err = session.doPrepare(sqlStr)
|
stmt, err = session.doPrepare(sqlStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
rawRows, err = stmt.Query(args...)
|
rawRows, err = stmt.Query(args...)
|
||||||
|
} else {
|
||||||
|
rawRows, err = session.DB().Query(sqlStr, args...)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rawRows, err = session.Tx.Query(sqlStr, args...)
|
rawRows, err = session.Tx.Query(sqlStr, args...)
|
||||||
}
|
}
|
||||||
|
@ -1490,7 +1363,6 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
|
|
||||||
table := session.Engine.autoMapType(dataStruct)
|
table := session.Engine.autoMapType(dataStruct)
|
||||||
return session.rows2Beans(rawRows, fields, fieldsCount, table, newElemFunc, sliceValueSetFunc)
|
return session.rows2Beans(rawRows, fields, fieldsCount, table, newElemFunc, sliceValueSetFunc)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
resultsSlice, err := session.query(sqlStr, args...)
|
resultsSlice, err := session.query(sqlStr, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1506,7 +1378,6 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
} else {
|
} else {
|
||||||
newValue = reflect.New(sliceElementType)
|
newValue = reflect.New(sliceElementType)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := session.scanMapIntoStruct(newValue.Interface(), results)
|
err := session.scanMapIntoStruct(newValue.Interface(), results)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1540,25 +1411,10 @@ func (session *Session) Find(rowsSlicePtr interface{}, condiBean ...interface{})
|
||||||
sliceValue.SetMapIndex(reflect.ValueOf(key), reflect.Indirect(reflect.ValueOf(newValue.Interface())))
|
sliceValue.SetMapIndex(reflect.ValueOf(key), reflect.Indirect(reflect.ValueOf(newValue.Interface())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (session *Session) queryRows(rawStmt **sql.Stmt, rawRows **sql.Rows, sqlStr string, args ...interface{}) error {
|
|
||||||
// var err error
|
|
||||||
// if session.IsAutoCommit {
|
|
||||||
// *rawStmt, err = session.doPrepare(sqlStr)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// *rawRows, err = (*rawStmt).Query(args...)
|
|
||||||
// } else {
|
|
||||||
// *rawRows, err = session.Tx.Query(sqlStr, args...)
|
|
||||||
// }
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Test if database is ok
|
// Test if database is ok
|
||||||
func (session *Session) Ping() error {
|
func (session *Session) Ping() error {
|
||||||
defer session.resetStatement()
|
defer session.resetStatement()
|
||||||
|
@ -1762,7 +1618,6 @@ type Cell *interface{}
|
||||||
func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
|
func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount int,
|
||||||
table *core.Table, newElemFunc func() reflect.Value,
|
table *core.Table, newElemFunc func() reflect.Value,
|
||||||
sliceValueSetFunc func(*reflect.Value)) error {
|
sliceValueSetFunc func(*reflect.Value)) error {
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var newValue reflect.Value = newElemFunc()
|
var newValue reflect.Value = newElemFunc()
|
||||||
bean := newValue.Interface()
|
bean := newValue.Interface()
|
||||||
|
@ -1772,7 +1627,6 @@ func (session *Session) rows2Beans(rows *core.Rows, fields []string, fieldsCount
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sliceValueSetFunc(&newValue)
|
sliceValueSetFunc(&newValue)
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1946,8 +1800,22 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
rawValueType == core.Int32Type {
|
rawValueType == core.Int32Type {
|
||||||
hasAssigned = true
|
hasAssigned = true
|
||||||
t := time.Unix(vv.Int(), 0).In(session.Engine.TZLocation)
|
t := time.Unix(vv.Int(), 0).In(session.Engine.TZLocation)
|
||||||
vv = reflect.ValueOf(t)
|
//vv = reflect.ValueOf(t)
|
||||||
fieldValue.Set(vv)
|
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||||
|
} else {
|
||||||
|
if d, ok := vv.Interface().([]uint8); ok {
|
||||||
|
hasAssigned = true
|
||||||
|
t, err := session.byte2Time(col, d)
|
||||||
|
//fmt.Println(string(d), t, err)
|
||||||
|
if err != nil {
|
||||||
|
session.Engine.LogError("byte2Time error:", err.Error())
|
||||||
|
hasAssigned = false
|
||||||
|
} else {
|
||||||
|
fieldValue.Set(reflect.ValueOf(t).Convert(fieldType))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic(fmt.Sprintf("rawValueType is %v, value is %v", rawValueType, vv.Interface()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
|
} else if nulVal, ok := fieldValue.Addr().Interface().(sql.Scanner); ok {
|
||||||
// !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
|
// !<winxxp>! 增加支持sql.Scanner接口的结构,如sql.NullString
|
||||||
|
@ -2008,8 +1876,10 @@ func (session *Session) _row2Bean(rows *core.Rows, fields []string, fieldsCount
|
||||||
pk[0] = uint8(vv.Uint())
|
pk[0] = uint8(vv.Uint())
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
pk[0] = vv.String()
|
pk[0] = vv.String()
|
||||||
|
case reflect.Slice:
|
||||||
|
pk[0], _ = strconv.ParseInt(string(rawValue.Interface().([]byte)), 10, 64)
|
||||||
default:
|
default:
|
||||||
panic("unsupported primary key type cascade")
|
panic(fmt.Sprintf("unsupported primary key type: %v, %v", rawValueType, fieldValue))
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isPKZero(pk) {
|
if !isPKZero(pk) {
|
||||||
|
@ -2180,7 +2050,7 @@ func (session *Session) query(sqlStr string, paramStr ...interface{}) (resultsSl
|
||||||
session.queryPreprocess(&sqlStr, paramStr...)
|
session.queryPreprocess(&sqlStr, paramStr...)
|
||||||
|
|
||||||
if session.IsAutoCommit {
|
if session.IsAutoCommit {
|
||||||
return session.innerQuery(session.DB(), sqlStr, paramStr...)
|
return session.innerQuery(sqlStr, paramStr...)
|
||||||
}
|
}
|
||||||
return session.txQuery(session.Tx, sqlStr, paramStr...)
|
return session.txQuery(session.Tx, sqlStr, paramStr...)
|
||||||
}
|
}
|
||||||
|
@ -2195,64 +2065,33 @@ func (session *Session) txQuery(tx *core.Tx, sqlStr string, params ...interface{
|
||||||
return rows2maps(rows)
|
return rows2maps(rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) queryX(sqlStr string, paramStr ...interface{}) (resultsSlice []map[string]string, err error) {
|
func (session *Session) innerQuery(sqlStr string, params ...interface{}) ([]map[string][]byte, error) {
|
||||||
|
var callback func() (*core.Stmt, *core.Rows, error)
|
||||||
session.queryPreprocess(&sqlStr, paramStr...)
|
if session.prepareStmt {
|
||||||
|
callback = func() (*core.Stmt, *core.Rows, error) {
|
||||||
if session.IsAutoCommit {
|
stmt, err := session.doPrepare(sqlStr)
|
||||||
return session.innerQuery2(session.DB(), sqlStr, paramStr...)
|
|
||||||
}
|
|
||||||
return session.txQuery2(session.Tx, sqlStr, paramStr...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (session *Session) txQuery2(tx *core.Tx, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) {
|
|
||||||
rows, err := tx.Query(sqlStr, params...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
return rows2Strings(rows)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (session *Session) innerQuery2(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string]string, err error) {
|
|
||||||
stmt, rows, err := session.Engine.LogSQLQueryTime(sqlStr, params, func() (*core.Stmt, *core.Rows, error) {
|
|
||||||
stmt, err := db.Prepare(sqlStr)
|
|
||||||
if err != nil {
|
|
||||||
return stmt, nil, err
|
|
||||||
}
|
}
|
||||||
rows, err := stmt.Query(params...)
|
rows, err := stmt.Query(params...)
|
||||||
|
if err != nil {
|
||||||
return stmt, rows, err
|
return nil, nil, err
|
||||||
})
|
}
|
||||||
|
return stmt, rows, nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback = func() (*core.Stmt, *core.Rows, error) {
|
||||||
|
rows, err := session.DB().Query(sqlStr, params...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return nil, rows, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, rows, err := session.Engine.LogSQLQueryTime(sqlStr, params, callback)
|
||||||
if rows != nil {
|
if rows != nil {
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
}
|
}
|
||||||
if stmt != nil {
|
|
||||||
defer stmt.Close()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return rows2Strings(rows)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (session *Session) innerQuery(db *core.DB, sqlStr string, params ...interface{}) (resultsSlice []map[string][]byte, err error) {
|
|
||||||
stmt, rows, err := session.Engine.LogSQLQueryTime(sqlStr, params, func() (*core.Stmt, *core.Rows, error) {
|
|
||||||
stmt, err := db.Prepare(sqlStr)
|
|
||||||
if err != nil {
|
|
||||||
return stmt, nil, err
|
|
||||||
}
|
|
||||||
rows, err := stmt.Query(params...)
|
|
||||||
|
|
||||||
return stmt, rows, err
|
|
||||||
})
|
|
||||||
if rows != nil {
|
|
||||||
defer rows.Close()
|
|
||||||
}
|
|
||||||
if stmt != nil {
|
|
||||||
defer stmt.Close()
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -2367,7 +2206,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
fieldValue := *ptrFieldValue
|
fieldValue := *ptrFieldValue
|
||||||
if col.IsAutoIncrement && fieldValue.Int() == 0 {
|
if col.IsAutoIncrement && isZero(fieldValue.Interface()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if col.MapType == core.ONLYFROMDB {
|
if col.MapType == core.ONLYFROMDB {
|
||||||
|
@ -2415,7 +2254,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||||
}
|
}
|
||||||
fieldValue := *ptrFieldValue
|
fieldValue := *ptrFieldValue
|
||||||
|
|
||||||
if col.IsAutoIncrement && fieldValue.Int() == 0 {
|
if col.IsAutoIncrement && isZero(fieldValue.Interface()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if col.MapType == core.ONLYFROMDB {
|
if col.MapType == core.ONLYFROMDB {
|
||||||
|
@ -2538,17 +2377,18 @@ func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.T
|
||||||
// time stamp
|
// time stamp
|
||||||
sd, err := strconv.ParseInt(sdata, 10, 64)
|
sd, err := strconv.ParseInt(sdata, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
x = time.Unix(0, sd)
|
x = time.Unix(sd, 0)
|
||||||
// !nashtsai! HACK mymysql driver is casuing Local location being change to CHAT and cause wrong time conversion
|
// !nashtsai! HACK mymysql driver is casuing Local location being change to CHAT and cause wrong time conversion
|
||||||
x = x.In(time.UTC)
|
//fmt.Println(x.In(session.Engine.TZLocation), "===")
|
||||||
x = time.Date(x.Year(), x.Month(), x.Day(), x.Hour(),
|
x = x.In(session.Engine.TZLocation)
|
||||||
x.Minute(), x.Second(), x.Nanosecond(), session.Engine.TZLocation)
|
//fmt.Println(x, "=====")
|
||||||
|
/*x = time.Date(x.Year(), x.Month(), x.Day(), x.Hour(),
|
||||||
|
x.Minute(), x.Second(), x.Nanosecond(), session.Engine.TZLocation)*/
|
||||||
session.Engine.LogDebugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
session.Engine.LogDebugf("time(0) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
||||||
} else {
|
} else {
|
||||||
session.Engine.LogDebugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
session.Engine.LogDebugf("time(0) err key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
||||||
}
|
}
|
||||||
} else if len(sdata) > 19 {
|
} else if len(sdata) > 19 && strings.Contains(sdata, "-") {
|
||||||
|
|
||||||
x, err = time.ParseInLocation(time.RFC3339Nano, sdata, session.Engine.TZLocation)
|
x, err = time.ParseInLocation(time.RFC3339Nano, sdata, session.Engine.TZLocation)
|
||||||
session.Engine.LogDebugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
session.Engine.LogDebugf("time(1) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -2560,7 +2400,7 @@ func (session *Session) byte2Time(col *core.Column, data []byte) (outTime time.T
|
||||||
session.Engine.LogDebugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
session.Engine.LogDebugf("time(3) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if len(sdata) == 19 {
|
} else if len(sdata) == 19 && strings.Contains(sdata, "-") {
|
||||||
x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, session.Engine.TZLocation)
|
x, err = time.ParseInLocation("2006-01-02 15:04:05", sdata, session.Engine.TZLocation)
|
||||||
session.Engine.LogDebugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
session.Engine.LogDebugf("time(4) key[%v]: %+v | sdata: [%v]\n", col.FieldName, x, sdata)
|
||||||
} else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' {
|
} else if len(sdata) == 10 && sdata[4] == '-' && sdata[7] == '-' {
|
||||||
|
@ -2664,7 +2504,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
} else {
|
} else {
|
||||||
x = 0
|
x = 0
|
||||||
}
|
}
|
||||||
//fmt.Println("######", x, data)
|
|
||||||
} else if strings.HasPrefix(sdata, "0x") {
|
} else if strings.HasPrefix(sdata, "0x") {
|
||||||
x, err = strconv.ParseInt(sdata, 16, 64)
|
x, err = strconv.ParseInt(sdata, 16, 64)
|
||||||
} else if strings.HasPrefix(sdata, "0") {
|
} else if strings.HasPrefix(sdata, "0") {
|
||||||
|
@ -2920,7 +2759,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
} else {
|
} else {
|
||||||
x = 0
|
x = 0
|
||||||
}
|
}
|
||||||
//fmt.Println("######", x, data)
|
|
||||||
} else if strings.HasPrefix(sdata, "0x") {
|
} else if strings.HasPrefix(sdata, "0x") {
|
||||||
x, err = strconv.ParseInt(sdata, 16, 64)
|
x, err = strconv.ParseInt(sdata, 16, 64)
|
||||||
} else if strings.HasPrefix(sdata, "0") {
|
} else if strings.HasPrefix(sdata, "0") {
|
||||||
|
@ -2946,7 +2784,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
} else {
|
} else {
|
||||||
x = 0
|
x = 0
|
||||||
}
|
}
|
||||||
//fmt.Println("######", x, data)
|
|
||||||
} else if strings.HasPrefix(sdata, "0x") {
|
} else if strings.HasPrefix(sdata, "0x") {
|
||||||
x1, err = strconv.ParseInt(sdata, 16, 64)
|
x1, err = strconv.ParseInt(sdata, 16, 64)
|
||||||
x = int(x1)
|
x = int(x1)
|
||||||
|
@ -2975,7 +2812,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
} else {
|
} else {
|
||||||
x = 0
|
x = 0
|
||||||
}
|
}
|
||||||
//fmt.Println("######", x, data)
|
|
||||||
} else if strings.HasPrefix(sdata, "0x") {
|
} else if strings.HasPrefix(sdata, "0x") {
|
||||||
x1, err = strconv.ParseInt(sdata, 16, 64)
|
x1, err = strconv.ParseInt(sdata, 16, 64)
|
||||||
x = int32(x1)
|
x = int32(x1)
|
||||||
|
@ -3004,7 +2840,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
} else {
|
} else {
|
||||||
x = 0
|
x = 0
|
||||||
}
|
}
|
||||||
//fmt.Println("######", x, data)
|
|
||||||
} else if strings.HasPrefix(sdata, "0x") {
|
} else if strings.HasPrefix(sdata, "0x") {
|
||||||
x1, err = strconv.ParseInt(sdata, 16, 64)
|
x1, err = strconv.ParseInt(sdata, 16, 64)
|
||||||
x = int8(x1)
|
x = int8(x1)
|
||||||
|
@ -3033,7 +2868,6 @@ func (session *Session) bytes2Value(col *core.Column, fieldValue *reflect.Value,
|
||||||
} else {
|
} else {
|
||||||
x = 0
|
x = 0
|
||||||
}
|
}
|
||||||
//fmt.Println("######", x, data)
|
|
||||||
} else if strings.HasPrefix(sdata, "0x") {
|
} else if strings.HasPrefix(sdata, "0x") {
|
||||||
x1, err = strconv.ParseInt(sdata, 16, 64)
|
x1, err = strconv.ParseInt(sdata, 16, 64)
|
||||||
x = int16(x1)
|
x = int16(x1)
|
||||||
|
@ -3211,10 +3045,8 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return fieldValue.String(), nil
|
return fieldValue.String(), nil
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
if fieldType == core.TimeType {
|
if fieldType.ConvertibleTo(core.TimeType) {
|
||||||
switch fieldValue.Interface().(type) {
|
t := fieldValue.Convert(core.TimeType).Interface().(time.Time)
|
||||||
case time.Time:
|
|
||||||
t := fieldValue.Interface().(time.Time)
|
|
||||||
if session.Engine.dialect.DBType() == core.MSSQL {
|
if session.Engine.dialect.DBType() == core.MSSQL {
|
||||||
if t.IsZero() {
|
if t.IsZero() {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -3222,9 +3054,6 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
}
|
}
|
||||||
tf := session.Engine.FormatTime(col.SQLType.Name, t)
|
tf := session.Engine.FormatTime(col.SQLType.Name, t)
|
||||||
return tf, nil
|
return tf, nil
|
||||||
default:
|
|
||||||
return fieldValue.Interface(), nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !col.SQLType.IsJson() {
|
if !col.SQLType.IsJson() {
|
||||||
|
@ -3234,18 +3063,11 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldTable := session.Engine.autoMapType(fieldValue)
|
fieldTable := session.Engine.autoMapType(fieldValue)
|
||||||
//if fieldTable, ok := session.Engine.Tables[fieldValue.Type()]; ok {
|
|
||||||
if len(fieldTable.PrimaryKeys) == 1 {
|
if len(fieldTable.PrimaryKeys) == 1 {
|
||||||
pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
|
pkField := reflect.Indirect(fieldValue).FieldByName(fieldTable.PKColumns()[0].FieldName)
|
||||||
return pkField.Interface(), nil
|
return pkField.Interface(), nil
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
} else {
|
|
||||||
return 0, fmt.Errorf("Unsupported type %v\n", fieldValue.Type())
|
|
||||||
=======
|
|
||||||
return 0, fmt.Errorf("no primary key for col %v", col.Name)
|
return 0, fmt.Errorf("no primary key for col %v", col.Name)
|
||||||
//}
|
|
||||||
>>>>>>> refs/remotes/go-xorm/master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if col.SQLType.IsText() {
|
if col.SQLType.IsText() {
|
||||||
|
@ -3263,7 +3085,6 @@ func (session *Session) value2Interface(col *core.Column, fieldValue reflect.Val
|
||||||
}
|
}
|
||||||
return bytes, nil
|
return bytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type())
|
return nil, fmt.Errorf("Unsupported type %v", fieldValue.Type())
|
||||||
case reflect.Complex64, reflect.Complex128:
|
case reflect.Complex64, reflect.Complex128:
|
||||||
bytes, err := json.Marshal(fieldValue.Interface())
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
|
@ -3431,19 +3252,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var v interface{} = id
|
v := int64ToInt(id, aiValue.Type().Kind())
|
||||||
switch aiValue.Type().Kind() {
|
|
||||||
case reflect.Int32:
|
|
||||||
v = int32(id)
|
|
||||||
case reflect.Int:
|
|
||||||
v = int(id)
|
|
||||||
case reflect.Uint32:
|
|
||||||
v = uint32(id)
|
|
||||||
case reflect.Uint64:
|
|
||||||
v = uint64(id)
|
|
||||||
case reflect.Uint:
|
|
||||||
v = uint(id)
|
|
||||||
}
|
|
||||||
aiValue.Set(reflect.ValueOf(v))
|
aiValue.Set(reflect.ValueOf(v))
|
||||||
|
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -3490,19 +3299,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
return 1, nil
|
return 1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var v interface{} = id
|
v := int64ToInt(id, aiValue.Type().Kind())
|
||||||
switch aiValue.Type().Kind() {
|
|
||||||
case reflect.Int32:
|
|
||||||
v = int32(id)
|
|
||||||
case reflect.Int:
|
|
||||||
v = int(id)
|
|
||||||
case reflect.Uint32:
|
|
||||||
v = uint32(id)
|
|
||||||
case reflect.Uint64:
|
|
||||||
v = uint64(id)
|
|
||||||
case reflect.Uint:
|
|
||||||
v = uint(id)
|
|
||||||
}
|
|
||||||
aiValue.Set(reflect.ValueOf(v))
|
aiValue.Set(reflect.ValueOf(v))
|
||||||
|
|
||||||
return 1, nil
|
return 1, nil
|
||||||
|
@ -3546,23 +3343,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
return res.RowsAffected()
|
return res.RowsAffected()
|
||||||
}
|
}
|
||||||
|
|
||||||
var v interface{} = id
|
v := int64ToInt(id, aiValue.Type().Kind())
|
||||||
switch aiValue.Type().Kind() {
|
|
||||||
case reflect.Int16:
|
|
||||||
v = int16(id)
|
|
||||||
case reflect.Int32:
|
|
||||||
v = int32(id)
|
|
||||||
case reflect.Int:
|
|
||||||
v = int(id)
|
|
||||||
case reflect.Uint16:
|
|
||||||
v = uint16(id)
|
|
||||||
case reflect.Uint32:
|
|
||||||
v = uint32(id)
|
|
||||||
case reflect.Uint64:
|
|
||||||
v = uint64(id)
|
|
||||||
case reflect.Uint:
|
|
||||||
v = uint(id)
|
|
||||||
}
|
|
||||||
aiValue.Set(reflect.ValueOf(v))
|
aiValue.Set(reflect.ValueOf(v))
|
||||||
|
|
||||||
return res.RowsAffected()
|
return res.RowsAffected()
|
||||||
|
@ -3639,7 +3420,8 @@ func (session *Session) cacheInsert(tables ...string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
||||||
if session.Statement.RefTable == nil || len(session.Statement.RefTable.PrimaryKeys) != 1 {
|
if session.Statement.RefTable == nil ||
|
||||||
|
session.Tx != nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3788,26 +3570,24 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
// --
|
// --
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if t.Kind() == reflect.Struct {
|
var isMap = t.Kind() == reflect.Map
|
||||||
|
var isStruct = t.Kind() == reflect.Struct
|
||||||
|
if isStruct {
|
||||||
table = session.Engine.TableInfo(bean)
|
table = session.Engine.TableInfo(bean)
|
||||||
session.Statement.RefTable = table
|
session.Statement.RefTable = table
|
||||||
|
|
||||||
if session.Statement.ColumnStr == "" {
|
if session.Statement.ColumnStr == "" {
|
||||||
colNames, args = buildUpdates(session.Engine, table, bean, false, false,
|
colNames, args = buildUpdates(session.Engine, table, bean, false, false,
|
||||||
false, false, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, false, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
<<<<<<< HEAD
|
|
||||||
session.Statement.mustColumnMap, session.Statement.columnMap, true)
|
|
||||||
=======
|
|
||||||
session.Statement.mustColumnMap, session.Statement.nullableMap,
|
session.Statement.mustColumnMap, session.Statement.nullableMap,
|
||||||
session.Statement.columnMap, true, session.Statement.unscoped)
|
session.Statement.columnMap, true, session.Statement.unscoped)
|
||||||
>>>>>>> refs/remotes/go-xorm/master
|
|
||||||
} else {
|
} else {
|
||||||
colNames, args, err = genCols(table, session, bean, true, true)
|
colNames, args, err = genCols(table, session, bean, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if t.Kind() == reflect.Map {
|
} else if isMap {
|
||||||
if session.Statement.RefTable == nil {
|
if session.Statement.RefTable == nil {
|
||||||
return 0, ErrTableNotFound
|
return 0, ErrTableNotFound
|
||||||
}
|
}
|
||||||
|
@ -3831,11 +3611,13 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
args = append(args, val)
|
args = append(args, val)
|
||||||
|
|
||||||
var colName = col.Name
|
var colName = col.Name
|
||||||
|
if isStruct {
|
||||||
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
session.afterClosures = append(session.afterClosures, func(bean interface{}) {
|
||||||
col := table.GetColumn(colName)
|
col := table.GetColumn(colName)
|
||||||
setColumnTime(bean, col, t)
|
setColumnTime(bean, col, t)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//for update action to like "column = column + ?"
|
//for update action to like "column = column + ?"
|
||||||
incColumns := session.Statement.getInc()
|
incColumns := session.Statement.getInc()
|
||||||
|
@ -3858,10 +3640,10 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
var condiColNames []string
|
var condiColNames []string
|
||||||
var condiArgs []interface{}
|
var condiArgs []interface{}
|
||||||
|
|
||||||
if len(condiBean) > 0 {
|
if !session.Statement.noAutoCondition && len(condiBean) > 0 {
|
||||||
condiColNames, condiArgs = buildConditions(session.Engine, session.Statement.RefTable, condiBean[0], true, true,
|
condiColNames, condiArgs = buildConditions(session.Engine, session.Statement.RefTable, condiBean[0], true, true,
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
session.Statement.unscoped, session.Statement.mustColumnMap)
|
session.Statement.unscoped, session.Statement.mustColumnMap, session.Statement.TableName(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
var condition = ""
|
var condition = ""
|
||||||
|
@ -3978,6 +3760,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
} else {
|
} else {
|
||||||
afterClosures := make([]func(interface{}), lenAfterClosures)
|
afterClosures := make([]func(interface{}), lenAfterClosures)
|
||||||
copy(afterClosures, session.afterClosures)
|
copy(afterClosures, session.afterClosures)
|
||||||
|
// FIXME: if bean is a map type, it will panic because map cannot be as map key
|
||||||
session.afterUpdateBeans[bean] = &afterClosures
|
session.afterUpdateBeans[bean] = &afterClosures
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3994,7 +3777,8 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
if session.Statement.RefTable == nil || len(session.Statement.RefTable.PrimaryKeys) != 1 {
|
if session.Statement.RefTable == nil ||
|
||||||
|
session.Tx != nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4019,15 +3803,25 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
if len(resultsSlice) > 0 {
|
if len(resultsSlice) > 0 {
|
||||||
for _, data := range resultsSlice {
|
for _, data := range resultsSlice {
|
||||||
var id int64
|
var id int64
|
||||||
if v, ok := data[session.Statement.RefTable.PrimaryKeys[0]]; !ok {
|
var pk core.PK = make([]interface{}, 0)
|
||||||
|
for _, col := range session.Statement.RefTable.PKColumns() {
|
||||||
|
if v, ok := data[col.Name]; !ok {
|
||||||
return errors.New("no id")
|
return errors.New("no id")
|
||||||
} else {
|
} else {
|
||||||
|
if col.SQLType.IsText() {
|
||||||
|
pk = append(pk, string(v))
|
||||||
|
} else if col.SQLType.IsNumeric() {
|
||||||
id, err = strconv.ParseInt(string(v), 10, 64)
|
id, err = strconv.ParseInt(string(v), 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
pk = append(pk, id)
|
||||||
|
} else {
|
||||||
|
return errors.New("not supported primary key type")
|
||||||
}
|
}
|
||||||
ids = append(ids, core.PK{id})
|
}
|
||||||
|
}
|
||||||
|
ids = append(ids, pk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /*else {
|
} /*else {
|
||||||
|
@ -4068,15 +3862,15 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
|
|
||||||
table := session.Engine.TableInfo(bean)
|
table := session.Engine.TableInfo(bean)
|
||||||
session.Statement.RefTable = table
|
session.Statement.RefTable = table
|
||||||
colNames, args := buildConditions(session.Engine, table, bean, true, true,
|
var colNames []string
|
||||||
|
var args []interface{}
|
||||||
|
|
||||||
|
if !session.Statement.noAutoCondition {
|
||||||
|
colNames, args = buildConditions(session.Engine, table, bean, true, true,
|
||||||
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
false, true, session.Statement.allUseBool, session.Statement.useAllCols,
|
||||||
<<<<<<< HEAD
|
|
||||||
session.Statement.unscoped, session.Statement.mustColumnMap)
|
|
||||||
=======
|
|
||||||
session.Statement.unscoped, session.Statement.mustColumnMap,
|
session.Statement.unscoped, session.Statement.mustColumnMap,
|
||||||
session.Statement.TableName(), false)
|
session.Statement.TableName(), false)
|
||||||
>>>>>>> refs/remotes/go-xorm/master
|
}
|
||||||
|
|
||||||
var condition = ""
|
var condition = ""
|
||||||
var andStr = session.Engine.dialect.AndStr()
|
var andStr = session.Engine.dialect.AndStr()
|
||||||
|
|
||||||
|
@ -4254,10 +4048,26 @@ func (s *Session) Sync2(beans ...interface{}) error {
|
||||||
engine.LogWarnf("Table %s column %s db type is %s, struct type is %s\n",
|
engine.LogWarnf("Table %s column %s db type is %s, struct type is %s\n",
|
||||||
table.Name, col.Name, curType, expectedType)
|
table.Name, col.Name, curType, expectedType)
|
||||||
}
|
}
|
||||||
|
} else if strings.HasPrefix(curType, core.Varchar) && strings.HasPrefix(expectedType, core.Varchar) {
|
||||||
|
if engine.dialect.DBType() == core.MYSQL {
|
||||||
|
if oriCol.Length < col.Length {
|
||||||
|
engine.LogInfof("Table %s column %s change type from varchar(%d) to varchar(%d)\n",
|
||||||
|
table.Name, col.Name, oriCol.Length, col.Length)
|
||||||
|
_, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
engine.LogWarnf("Table %s column %s db type is %s, struct type is %s",
|
engine.LogWarnf("Table %s column %s db type is %s, struct type is %s",
|
||||||
table.Name, col.Name, curType, expectedType)
|
table.Name, col.Name, curType, expectedType)
|
||||||
}
|
}
|
||||||
|
} else if expectedType == core.Varchar {
|
||||||
|
if engine.dialect.DBType() == core.MYSQL {
|
||||||
|
if oriCol.Length < col.Length {
|
||||||
|
engine.LogInfof("Table %s column %s change type from varchar(%d) to varchar(%d)\n",
|
||||||
|
table.Name, col.Name, oriCol.Length, col.Length)
|
||||||
|
_, err = engine.Exec(engine.dialect.ModifyColumnSql(table.Name, col))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if col.Default != oriCol.Default {
|
if col.Default != oriCol.Default {
|
||||||
engine.LogWarnf("Table %s Column %s db default is %s, struct default is %s",
|
engine.LogWarnf("Table %s Column %s db default is %s, struct default is %s",
|
||||||
|
|
24
statement.go
24
statement.go
|
@ -66,6 +66,7 @@ type Statement struct {
|
||||||
BeanArgs []interface{}
|
BeanArgs []interface{}
|
||||||
UseCache bool
|
UseCache bool
|
||||||
UseAutoTime bool
|
UseAutoTime bool
|
||||||
|
noAutoCondition bool
|
||||||
IsDistinct bool
|
IsDistinct bool
|
||||||
IsForUpdate bool
|
IsForUpdate bool
|
||||||
TableAlias string
|
TableAlias string
|
||||||
|
@ -103,6 +104,7 @@ func (statement *Statement) Init() {
|
||||||
statement.BeanArgs = make([]interface{}, 0)
|
statement.BeanArgs = make([]interface{}, 0)
|
||||||
statement.UseCache = true
|
statement.UseCache = true
|
||||||
statement.UseAutoTime = true
|
statement.UseAutoTime = true
|
||||||
|
statement.noAutoCondition = false
|
||||||
statement.IsDistinct = false
|
statement.IsDistinct = false
|
||||||
statement.IsForUpdate = false
|
statement.IsForUpdate = false
|
||||||
statement.TableAlias = ""
|
statement.TableAlias = ""
|
||||||
|
@ -119,6 +121,15 @@ func (statement *Statement) Init() {
|
||||||
statement.exprColumns = make(map[string]exprParam)
|
statement.exprColumns = make(map[string]exprParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NoAutoCondition
|
||||||
|
func (statement *Statement) NoAutoCondition(no ...bool) *Statement {
|
||||||
|
statement.noAutoCondition = true
|
||||||
|
if len(no) > 0 {
|
||||||
|
statement.noAutoCondition = no[0]
|
||||||
|
}
|
||||||
|
return statement
|
||||||
|
}
|
||||||
|
|
||||||
// add the raw sql statement
|
// add the raw sql statement
|
||||||
func (statement *Statement) Sql(querystring string, args ...interface{}) *Statement {
|
func (statement *Statement) Sql(querystring string, args ...interface{}) *Statement {
|
||||||
statement.RawSQL = querystring
|
statement.RawSQL = querystring
|
||||||
|
@ -182,7 +193,7 @@ func (statement *Statement) Table(tableNameOrBean interface{}) *Statement {
|
||||||
return statement
|
return statement
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto generating conditions according a struct
|
// Auto generating update columnes and values according a struct
|
||||||
func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
includeVersion bool, includeUpdated bool, includeNil bool,
|
includeVersion bool, includeUpdated bool, includeNil bool,
|
||||||
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
includeAutoIncr bool, allUseBool bool, useAllCols bool,
|
||||||
|
@ -211,10 +222,6 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if engine.dialect.DBType() == core.MSSQL && col.SQLType.Name == core.Text {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
fieldValuePtr, err := col.ValueOf(bean)
|
fieldValuePtr, err := col.ValueOf(bean)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
engine.LogError(err)
|
engine.LogError(err)
|
||||||
|
@ -338,7 +345,6 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
if len(table.PrimaryKeys) == 1 {
|
if len(table.PrimaryKeys) == 1 {
|
||||||
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
pkField := reflect.Indirect(fieldValue).FieldByName(table.PKColumns()[0].FieldName)
|
||||||
// fix non-int pk issues
|
// fix non-int pk issues
|
||||||
//if pkField.Int() != 0 {
|
|
||||||
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
if pkField.IsValid() && !isZero(pkField.Interface()) {
|
||||||
val = pkField.Interface()
|
val = pkField.Interface()
|
||||||
} else {
|
} else {
|
||||||
|
@ -364,12 +370,14 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Array, reflect.Slice, reflect.Map:
|
case reflect.Array, reflect.Slice, reflect.Map:
|
||||||
|
if !requiredField {
|
||||||
if fieldValue == reflect.Zero(fieldType) {
|
if fieldValue == reflect.Zero(fieldType) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
|
if fieldValue.IsNil() || !fieldValue.IsValid() || fieldValue.Len() == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if col.SQLType.IsText() {
|
if col.SQLType.IsText() {
|
||||||
bytes, err := json.Marshal(fieldValue.Interface())
|
bytes, err := json.Marshal(fieldValue.Interface())
|
||||||
|
@ -1122,12 +1130,14 @@ func (statement *Statement) genGetSql(bean interface{}) (string, []interface{})
|
||||||
|
|
||||||
var addedTableName = (len(statement.JoinStr) > 0)
|
var addedTableName = (len(statement.JoinStr) > 0)
|
||||||
|
|
||||||
|
if !statement.noAutoCondition {
|
||||||
colNames, args := buildConditions(statement.Engine, table, bean, true, true,
|
colNames, args := buildConditions(statement.Engine, table, bean, true, true,
|
||||||
false, true, statement.allUseBool, statement.useAllCols,
|
false, true, statement.allUseBool, statement.useAllCols,
|
||||||
statement.unscoped, statement.mustColumnMap, statement.TableName(), addedTableName)
|
statement.unscoped, statement.mustColumnMap, statement.TableName(), addedTableName)
|
||||||
|
|
||||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ")
|
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.dialect.AndStr()+" ")
|
||||||
statement.BeanArgs = args
|
statement.BeanArgs = args
|
||||||
|
}
|
||||||
|
|
||||||
var columnStr string = statement.ColumnStr
|
var columnStr string = statement.ColumnStr
|
||||||
if len(statement.selectStr) > 0 {
|
if len(statement.selectStr) > 0 {
|
||||||
|
@ -1183,12 +1193,14 @@ func (statement *Statement) genCountSql(bean interface{}) (string, []interface{}
|
||||||
|
|
||||||
var addedTableName = (len(statement.JoinStr) > 0)
|
var addedTableName = (len(statement.JoinStr) > 0)
|
||||||
|
|
||||||
|
if !statement.noAutoCondition {
|
||||||
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,
|
colNames, args := buildConditions(statement.Engine, table, bean, true, true, false,
|
||||||
true, statement.allUseBool, statement.useAllCols,
|
true, statement.allUseBool, statement.useAllCols,
|
||||||
statement.unscoped, statement.mustColumnMap, statement.TableName(), addedTableName)
|
statement.unscoped, statement.mustColumnMap, statement.TableName(), addedTableName)
|
||||||
|
|
||||||
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
|
statement.ConditionStr = strings.Join(colNames, " "+statement.Engine.Dialect().AndStr()+" ")
|
||||||
statement.BeanArgs = args
|
statement.BeanArgs = args
|
||||||
|
}
|
||||||
|
|
||||||
// count(index fieldname) > count(0) > count(*)
|
// count(index fieldname) > count(0) > count(*)
|
||||||
var id string = "*"
|
var id string = "*"
|
||||||
|
|
Loading…
Reference in New Issue