fix bug on cache delete (#703)
* fix bug on cache delete * fix cache issues and improve the tests
This commit is contained in:
parent
763e1b21e6
commit
265dd66928
22
cache_lru.go
22
cache_lru.go
|
@ -21,7 +21,6 @@ type LRUCacher struct {
|
||||||
sqlIndex map[string]map[string]*list.Element
|
sqlIndex map[string]map[string]*list.Element
|
||||||
store core.CacheStore
|
store core.CacheStore
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
// maxSize int
|
|
||||||
MaxElementSize int
|
MaxElementSize int
|
||||||
Expired time.Duration
|
Expired time.Duration
|
||||||
GcInterval time.Duration
|
GcInterval time.Duration
|
||||||
|
@ -54,8 +53,6 @@ func (m *LRUCacher) RunGC() {
|
||||||
|
|
||||||
// GC check ids lit and sql list to remove all element expired
|
// GC check ids lit and sql list to remove all element expired
|
||||||
func (m *LRUCacher) GC() {
|
func (m *LRUCacher) GC() {
|
||||||
//fmt.Println("begin gc ...")
|
|
||||||
//defer fmt.Println("end gc ...")
|
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
defer m.mutex.Unlock()
|
||||||
var removedNum int
|
var removedNum int
|
||||||
|
@ -64,12 +61,10 @@ func (m *LRUCacher) GC() {
|
||||||
time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
|
time.Now().Sub(e.Value.(*idNode).lastVisit) > m.Expired {
|
||||||
removedNum++
|
removedNum++
|
||||||
next := e.Next()
|
next := e.Next()
|
||||||
//fmt.Println("removing ...", e.Value)
|
|
||||||
node := e.Value.(*idNode)
|
node := e.Value.(*idNode)
|
||||||
m.delBean(node.tbName, node.id)
|
m.delBean(node.tbName, node.id)
|
||||||
e = next
|
e = next
|
||||||
} else {
|
} else {
|
||||||
//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.idList.Len())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,12 +75,10 @@ func (m *LRUCacher) GC() {
|
||||||
time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
|
time.Now().Sub(e.Value.(*sqlNode).lastVisit) > m.Expired {
|
||||||
removedNum++
|
removedNum++
|
||||||
next := e.Next()
|
next := e.Next()
|
||||||
//fmt.Println("removing ...", e.Value)
|
|
||||||
node := e.Value.(*sqlNode)
|
node := e.Value.(*sqlNode)
|
||||||
m.delIds(node.tbName, node.sql)
|
m.delIds(node.tbName, node.sql)
|
||||||
e = next
|
e = next
|
||||||
} else {
|
} else {
|
||||||
//fmt.Printf("removing %d cache nodes ..., left %d\n", removedNum, m.sqlList.Len())
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,7 +109,6 @@ func (m *LRUCacher) GetIds(tableName, sql string) interface{} {
|
||||||
}
|
}
|
||||||
|
|
||||||
m.delIds(tableName, sql)
|
m.delIds(tableName, sql)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +126,6 @@ func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
|
||||||
// if expired, remove the node and return nil
|
// if expired, remove the node and return nil
|
||||||
if time.Now().Sub(lastTime) > m.Expired {
|
if time.Now().Sub(lastTime) > m.Expired {
|
||||||
m.delBean(tableName, id)
|
m.delBean(tableName, id)
|
||||||
//m.clearIds(tableName)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
m.idList.MoveToBack(el)
|
m.idList.MoveToBack(el)
|
||||||
|
@ -148,7 +139,6 @@ func (m *LRUCacher) GetBean(tableName string, id string) interface{} {
|
||||||
|
|
||||||
// store bean is not exist, then remove memory's index
|
// store bean is not exist, then remove memory's index
|
||||||
m.delBean(tableName, id)
|
m.delBean(tableName, id)
|
||||||
//m.clearIds(tableName)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +156,8 @@ func (m *LRUCacher) clearIds(tableName string) {
|
||||||
// ClearIds clears all sql-ids mapping on table tableName from cache
|
// ClearIds clears all sql-ids mapping on table tableName from cache
|
||||||
func (m *LRUCacher) ClearIds(tableName string) {
|
func (m *LRUCacher) ClearIds(tableName string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.clearIds(tableName)
|
m.clearIds(tableName)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LRUCacher) clearBeans(tableName string) {
|
func (m *LRUCacher) clearBeans(tableName string) {
|
||||||
|
@ -184,14 +174,13 @@ func (m *LRUCacher) clearBeans(tableName string) {
|
||||||
// ClearBeans clears all beans in some table
|
// ClearBeans clears all beans in some table
|
||||||
func (m *LRUCacher) ClearBeans(tableName string) {
|
func (m *LRUCacher) ClearBeans(tableName string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.clearBeans(tableName)
|
m.clearBeans(tableName)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutIds pus ids into table
|
// PutIds pus ids into table
|
||||||
func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
if _, ok := m.sqlIndex[tableName]; !ok {
|
if _, ok := m.sqlIndex[tableName]; !ok {
|
||||||
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
m.sqlIndex[tableName] = make(map[string]*list.Element)
|
||||||
}
|
}
|
||||||
|
@ -207,12 +196,12 @@ func (m *LRUCacher) PutIds(tableName, sql string, ids interface{}) {
|
||||||
node := e.Value.(*sqlNode)
|
node := e.Value.(*sqlNode)
|
||||||
m.delIds(node.tbName, node.sql)
|
m.delIds(node.tbName, node.sql)
|
||||||
}
|
}
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutBean puts beans into table
|
// PutBean puts beans into table
|
||||||
func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
var el *list.Element
|
var el *list.Element
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
|
@ -229,6 +218,7 @@ func (m *LRUCacher) PutBean(tableName string, id string, obj interface{}) {
|
||||||
node := e.Value.(*idNode)
|
node := e.Value.(*idNode)
|
||||||
m.delBean(node.tbName, node.id)
|
m.delBean(node.tbName, node.id)
|
||||||
}
|
}
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LRUCacher) delIds(tableName, sql string) {
|
func (m *LRUCacher) delIds(tableName, sql string) {
|
||||||
|
@ -244,8 +234,8 @@ func (m *LRUCacher) delIds(tableName, sql string) {
|
||||||
// DelIds deletes ids
|
// DelIds deletes ids
|
||||||
func (m *LRUCacher) DelIds(tableName, sql string) {
|
func (m *LRUCacher) DelIds(tableName, sql string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.delIds(tableName, sql)
|
m.delIds(tableName, sql)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LRUCacher) delBean(tableName string, id string) {
|
func (m *LRUCacher) delBean(tableName string, id string) {
|
||||||
|
@ -261,8 +251,8 @@ func (m *LRUCacher) delBean(tableName string, id string) {
|
||||||
// DelBean deletes beans in some table
|
// DelBean deletes beans in some table
|
||||||
func (m *LRUCacher) DelBean(tableName string, id string) {
|
func (m *LRUCacher) DelBean(tableName string, id string) {
|
||||||
m.mutex.Lock()
|
m.mutex.Lock()
|
||||||
defer m.mutex.Unlock()
|
|
||||||
m.delBean(tableName, id)
|
m.delBean(tableName, id)
|
||||||
|
m.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
type idNode struct {
|
type idNode struct {
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/go-xorm/core"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLRUCache(t *testing.T) {
|
||||||
|
type CacheObject1 struct {
|
||||||
|
Id int64
|
||||||
|
}
|
||||||
|
|
||||||
|
store := NewMemoryStore()
|
||||||
|
cacher := NewLRUCacher(store, 10000)
|
||||||
|
|
||||||
|
tableName := "cache_object1"
|
||||||
|
pks := []core.PK{
|
||||||
|
{1},
|
||||||
|
{2},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pk := range pks {
|
||||||
|
sid, err := pk.ToString()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
cacher.PutIds(tableName, "select * from cache_object1", sid)
|
||||||
|
ids := cacher.GetIds(tableName, "select * from cache_object1")
|
||||||
|
assert.EqualValues(t, sid, ids)
|
||||||
|
|
||||||
|
cacher.ClearIds(tableName)
|
||||||
|
ids2 := cacher.GetIds(tableName, "select * from cache_object1")
|
||||||
|
assert.Nil(t, ids2)
|
||||||
|
|
||||||
|
obj2 := cacher.GetBean(tableName, sid)
|
||||||
|
assert.Nil(t, obj2)
|
||||||
|
|
||||||
|
var obj = new(CacheObject1)
|
||||||
|
cacher.PutBean(tableName, sid, obj)
|
||||||
|
obj3 := cacher.GetBean(tableName, sid)
|
||||||
|
assert.EqualValues(t, obj, obj3)
|
||||||
|
|
||||||
|
cacher.DelBean(tableName, sid)
|
||||||
|
obj4 := cacher.GetBean(tableName, sid)
|
||||||
|
assert.Nil(t, obj4)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMemoryStore(t *testing.T) {
|
||||||
|
store := NewMemoryStore()
|
||||||
|
var kvs = map[string]interface{}{
|
||||||
|
"a": "b",
|
||||||
|
}
|
||||||
|
for k, v := range kvs {
|
||||||
|
assert.NoError(t, store.Put(k, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range kvs {
|
||||||
|
val, err := store.Get(k)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, v, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, _ := range kvs {
|
||||||
|
err := store.Del(k)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, _ := range kvs {
|
||||||
|
_, err := store.Get(k)
|
||||||
|
assert.EqualValues(t, ErrNotExist, err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,7 @@ func TestCacheFind(t *testing.T) {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldCacher := testEngine.Cacher
|
||||||
cacher := NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)
|
cacher := NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)
|
||||||
testEngine.SetDefaultCacher(cacher)
|
testEngine.SetDefaultCacher(cacher)
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ func TestCacheFind(t *testing.T) {
|
||||||
assert.Equal(t, inserts[i].Password, box.Password)
|
assert.Equal(t, inserts[i].Password, box.Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
testEngine.SetDefaultCacher(nil)
|
testEngine.SetDefaultCacher(oldCacher)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCacheFind2(t *testing.T) {
|
func TestCacheFind2(t *testing.T) {
|
||||||
|
@ -70,6 +71,7 @@ func TestCacheFind2(t *testing.T) {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldCacher := testEngine.Cacher
|
||||||
cacher := NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)
|
cacher := NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)
|
||||||
testEngine.SetDefaultCacher(cacher)
|
testEngine.SetDefaultCacher(cacher)
|
||||||
|
|
||||||
|
@ -108,7 +110,7 @@ func TestCacheFind2(t *testing.T) {
|
||||||
assert.Equal(t, inserts[i].Password, box.Password)
|
assert.Equal(t, inserts[i].Password, box.Password)
|
||||||
}
|
}
|
||||||
|
|
||||||
testEngine.SetDefaultCacher(nil)
|
testEngine.SetDefaultCacher(oldCacher)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCacheGet(t *testing.T) {
|
func TestCacheGet(t *testing.T) {
|
||||||
|
@ -120,6 +122,7 @@ func TestCacheGet(t *testing.T) {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldCacher := testEngine.Cacher
|
||||||
cacher := NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)
|
cacher := NewLRUCacher2(NewMemoryStore(), time.Hour, 10000)
|
||||||
testEngine.SetDefaultCacher(cacher)
|
testEngine.SetDefaultCacher(cacher)
|
||||||
|
|
||||||
|
@ -148,5 +151,5 @@ func TestCacheGet(t *testing.T) {
|
||||||
assert.EqualValues(t, "user1", box2.Username)
|
assert.EqualValues(t, "user1", box2.Username)
|
||||||
assert.EqualValues(t, "pass1", box2.Password)
|
assert.EqualValues(t, "pass1", box2.Password)
|
||||||
|
|
||||||
testEngine.SetDefaultCacher(nil)
|
testEngine.SetDefaultCacher(oldCacher)
|
||||||
}
|
}
|
||||||
|
|
11
circle.yml
11
circle.yml
|
@ -21,7 +21,16 @@ database:
|
||||||
test:
|
test:
|
||||||
override:
|
override:
|
||||||
# './...' is a relative pattern which means all subdirectories
|
# './...' is a relative pattern which means all subdirectories
|
||||||
- go test -v -race -db="sqlite3::mysql::mymysql::postgres" -conn_str="./test.db::root:@/xorm_test::xorm_test/root/::dbname=xorm_test sslmode=disable" -coverprofile=coverage.txt -covermode=atomic
|
- go get -u github.com/wadey/gocovmerge;
|
||||||
|
- go test -v -race -db="sqlite3" -conn_str="./test.db" -coverprofile=coverage1-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="sqlite3" -conn_str="./test.db" -cache=true -coverprofile=coverage1-2.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mysql" -conn_str="root:@/xorm_test" -coverprofile=coverage2-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mysql" -conn_str="root:@/xorm_test" -cache=true -coverprofile=coverage2-2.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mymysql" -conn_str="xorm_test/root/" -coverprofile=coverage3-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="mymysql" -conn_str="xorm_test/root/" -cache=true -coverprofile=coverage3-2.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -coverprofile=coverage4-1.txt -covermode=atomic
|
||||||
|
- go test -v -race -db="postgres" -conn_str="dbname=xorm_test sslmode=disable" -cache=true -coverprofile=coverage4-2.txt -covermode=atomic
|
||||||
|
- gocovmerge coverage1-1.txt coverage1-2.txt coverage2-1.txt coverage2-2.txt coverage3-1.txt coverage3-2.txt coverage4-1.txt coverage4-2.txt > coverage.txt
|
||||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./sqlite3.sh
|
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./sqlite3.sh
|
||||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./mysql.sh
|
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./mysql.sh
|
||||||
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh
|
- cd /home/ubuntu/.go_workspace/src/github.com/go-xorm/tests && ./postgres.sh
|
||||||
|
|
|
@ -42,24 +42,24 @@ func TestBefore_Get(t *testing.T) {
|
||||||
func TestBefore_Find(t *testing.T) {
|
func TestBefore_Find(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type BeforeTable struct {
|
type BeforeTable2 struct {
|
||||||
Id int64
|
Id int64
|
||||||
Name string
|
Name string
|
||||||
Val string `xorm:"-"`
|
Val string `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(BeforeTable)))
|
assert.NoError(t, testEngine.Sync2(new(BeforeTable2)))
|
||||||
|
|
||||||
cnt, err := testEngine.Insert([]BeforeTable{
|
cnt, err := testEngine.Insert([]BeforeTable2{
|
||||||
{Name: "test1"},
|
{Name: "test1"},
|
||||||
{Name: "test2"},
|
{Name: "test2"},
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 2, cnt)
|
assert.EqualValues(t, 2, cnt)
|
||||||
|
|
||||||
var be []BeforeTable
|
var be []BeforeTable2
|
||||||
err = testEngine.Before(func(bean interface{}) {
|
err = testEngine.Before(func(bean interface{}) {
|
||||||
bean.(*BeforeTable).Val = "val"
|
bean.(*BeforeTable2).Val = "val"
|
||||||
}).Find(&be)
|
}).Find(&be)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 2, len(be))
|
assert.Equal(t, 2, len(be))
|
||||||
|
|
|
@ -14,14 +14,14 @@ import (
|
||||||
func TestSetExpr(t *testing.T) {
|
func TestSetExpr(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type User struct {
|
type UserExpr struct {
|
||||||
Id int64
|
Id int64
|
||||||
Show bool
|
Show bool
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(User)))
|
assert.NoError(t, testEngine.Sync2(new(UserExpr)))
|
||||||
|
|
||||||
cnt, err := testEngine.Insert(&User{
|
cnt, err := testEngine.Insert(&UserExpr{
|
||||||
Show: true,
|
Show: true,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
@ -31,7 +31,7 @@ func TestSetExpr(t *testing.T) {
|
||||||
if testEngine.dialect.DBType() == core.MSSQL {
|
if testEngine.dialect.DBType() == core.MSSQL {
|
||||||
not = "~"
|
not = "~"
|
||||||
}
|
}
|
||||||
cnt, err = testEngine.SetExpr("show", not+" `show`").ID(1).Update(new(User))
|
cnt, err = testEngine.SetExpr("show", not+" `show`").ID(1).Update(new(UserExpr))
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,14 +12,14 @@ import (
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
func (session *Session) cacheDelete(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
|
||||||
if session.statement.RefTable == nil ||
|
if table == nil ||
|
||||||
session.tx != nil {
|
session.tx != nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, filter := range session.engine.dialect.Filters() {
|
for _, filter := range session.engine.dialect.Filters() {
|
||||||
sqlStr = filter.Do(sqlStr, session.engine.dialect, session.statement.RefTable)
|
sqlStr = filter.Do(sqlStr, session.engine.dialect, table)
|
||||||
}
|
}
|
||||||
|
|
||||||
newsql := session.statement.convertIDSQL(sqlStr)
|
newsql := session.statement.convertIDSQL(sqlStr)
|
||||||
|
@ -27,8 +27,8 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
cacher := session.engine.getCacher2(session.statement.RefTable)
|
cacher := session.engine.getCacher2(table)
|
||||||
tableName := session.statement.TableName()
|
pkColumns := table.PKColumns()
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resultsSlice, err := session.queryBytes(newsql, args...)
|
resultsSlice, err := session.queryBytes(newsql, args...)
|
||||||
|
@ -40,7 +40,7 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
for _, data := range resultsSlice {
|
for _, data := range resultsSlice {
|
||||||
var id int64
|
var id int64
|
||||||
var pk core.PK = make([]interface{}, 0)
|
var pk core.PK = make([]interface{}, 0)
|
||||||
for _, col := range session.statement.RefTable.PKColumns() {
|
for _, col := range pkColumns {
|
||||||
if v, ok := data[col.Name]; !ok {
|
if v, ok := data[col.Name]; !ok {
|
||||||
return errors.New("no id")
|
return errors.New("no id")
|
||||||
} else if col.SQLType.IsText() {
|
} else if col.SQLType.IsText() {
|
||||||
|
@ -58,20 +58,17 @@ func (session *Session) cacheDelete(sqlStr string, args ...interface{}) error {
|
||||||
ids = append(ids, pk)
|
ids = append(ids, pk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /*else {
|
}
|
||||||
session.engine.LogDebug("delete cache sql %v", newsql)
|
|
||||||
cacher.DelIds(tableName, genSqlKey(newsql, args))
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
session.engine.logger.Debug("[cacheDelete] delete cache obj", tableName, id)
|
session.engine.logger.Debug("[cacheDelete] delete cache obj:", tableName, id)
|
||||||
sid, err := id.ToString()
|
sid, err := id.ToString()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cacher.DelBean(tableName, sid)
|
cacher.DelBean(tableName, sid)
|
||||||
}
|
}
|
||||||
session.engine.logger.Debug("[cacheDelete] clear cache sql", tableName)
|
session.engine.logger.Debug("[cacheDelete] clear cache table:", tableName)
|
||||||
cacher.ClearIds(tableName)
|
cacher.ClearIds(tableName)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -85,7 +82,6 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
if err := session.statement.setRefValue(rValue(bean)); err != nil {
|
if err := session.statement.setRefValue(rValue(bean)); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
var table = session.statement.RefTable
|
|
||||||
|
|
||||||
// handle before delete processors
|
// handle before delete processors
|
||||||
for _, closure := range session.beforeClosures {
|
for _, closure := range session.beforeClosures {
|
||||||
|
@ -105,7 +101,9 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
return 0, ErrNeedDeletedCond
|
return 0, ErrNeedDeletedCond
|
||||||
}
|
}
|
||||||
|
|
||||||
var tableName = session.engine.Quote(session.statement.TableName())
|
var tableNameNoQuote = session.statement.TableName()
|
||||||
|
var tableName = session.engine.Quote(tableNameNoQuote)
|
||||||
|
var table = session.statement.RefTable
|
||||||
var deleteSQL string
|
var deleteSQL string
|
||||||
if len(condSQL) > 0 {
|
if len(condSQL) > 0 {
|
||||||
deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL)
|
deleteSQL = fmt.Sprintf("DELETE FROM %v WHERE %v", tableName, condSQL)
|
||||||
|
@ -201,10 +199,11 @@ func (session *Session) Delete(bean interface{}) (int64, error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(session.statement.RefTable); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheDelete(deleteSQL, argsForCache...)
|
session.cacheDelete(table, tableNameNoQuote, deleteSQL, argsForCache...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.statement.RefTable = table
|
||||||
res, err := session.exec(realSQL, condArgs...)
|
res, err := session.exec(realSQL, condArgs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
|
|
@ -137,3 +137,35 @@ func TestDeleted(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 2, len(records3))
|
assert.EqualValues(t, 2, len(records3))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCacheDelete(t *testing.T) {
|
||||||
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
|
oldCacher := testEngine.Cacher
|
||||||
|
cacher := NewLRUCacher(NewMemoryStore(), 1000)
|
||||||
|
testEngine.SetDefaultCacher(cacher)
|
||||||
|
|
||||||
|
type CacheDeleteStruct struct {
|
||||||
|
Id int64
|
||||||
|
}
|
||||||
|
|
||||||
|
err := testEngine.CreateTables(&CacheDeleteStruct{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = testEngine.Insert(&CacheDeleteStruct{})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
aff, err := testEngine.Delete(&CacheDeleteStruct{
|
||||||
|
Id: 1,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, aff, 1)
|
||||||
|
|
||||||
|
aff, err = testEngine.Unscoped().Delete(&CacheDeleteStruct{
|
||||||
|
Id: 1,
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, aff, 0)
|
||||||
|
|
||||||
|
testEngine.SetDefaultCacher(oldCacher)
|
||||||
|
}
|
||||||
|
|
|
@ -293,12 +293,11 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
}
|
}
|
||||||
|
|
||||||
tableName := session.statement.TableName()
|
tableName := session.statement.TableName()
|
||||||
|
|
||||||
table := session.statement.RefTable
|
table := session.statement.RefTable
|
||||||
cacher := session.engine.getCacher2(table)
|
cacher := session.engine.getCacher2(table)
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rows, err := session.NoCache().queryRows(newsql, args...)
|
rows, err := session.queryRows(newsql, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -328,13 +327,13 @@ func (session *Session) cacheFind(t reflect.Type, sqlStr string, rowsSlicePtr in
|
||||||
ids = append(ids, pk)
|
ids = append(ids, pk)
|
||||||
}
|
}
|
||||||
|
|
||||||
session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, newsql, args)
|
session.engine.logger.Debug("[cacheFind] cache sql:", ids, tableName, sqlStr, newsql, args)
|
||||||
err = core.PutCacheSql(cacher, ids, tableName, newsql, args)
|
err = core.PutCacheSql(cacher, ids, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session.engine.logger.Debug("[cacheFind] cache hit sql:", newsql, args)
|
session.engine.logger.Debug("[cacheFind] cache hit sql:", tableName, sqlStr, newsql, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||||
|
|
|
@ -125,8 +125,8 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
cacher := session.engine.getCacher2(session.statement.RefTable)
|
cacher := session.engine.getCacher2(session.statement.RefTable)
|
||||||
tableName := session.statement.TableName()
|
tableName := session.statement.TableName()
|
||||||
session.engine.logger.Debug("[cacheGet] find sql:", newsql, args)
|
session.engine.logger.Debug("[cacheGet] find sql:", newsql, args)
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
|
||||||
table := session.statement.RefTable
|
table := session.statement.RefTable
|
||||||
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var res = make([]string, len(table.PrimaryKeys))
|
var res = make([]string, len(table.PrimaryKeys))
|
||||||
rows, err := session.NoCache().queryRows(newsql, args...)
|
rows, err := session.NoCache().queryRows(newsql, args...)
|
||||||
|
@ -166,7 +166,7 @@ func (session *Session) cacheGet(bean interface{}, sqlStr string, args ...interf
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql)
|
session.engine.logger.Debug("[cacheGet] cache hit sql:", newsql, ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ids) > 0 {
|
if len(ids) > 0 {
|
||||||
|
|
|
@ -213,22 +213,23 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||||
|
|
||||||
var sql = "INSERT INTO %s (%v%v%v) VALUES (%v)"
|
var sql = "INSERT INTO %s (%v%v%v) VALUES (%v)"
|
||||||
var statement string
|
var statement string
|
||||||
|
var tableName = session.statement.TableName()
|
||||||
if session.engine.dialect.DBType() == core.ORACLE {
|
if session.engine.dialect.DBType() == core.ORACLE {
|
||||||
sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL"
|
sql = "INSERT ALL INTO %s (%v%v%v) VALUES (%v) SELECT 1 FROM DUAL"
|
||||||
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
temp := fmt.Sprintf(") INTO %s (%v%v%v) VALUES (",
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||||
session.engine.QuoteStr())
|
session.engine.QuoteStr())
|
||||||
statement = fmt.Sprintf(sql,
|
statement = fmt.Sprintf(sql,
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colMultiPlaces, temp))
|
strings.Join(colMultiPlaces, temp))
|
||||||
} else {
|
} else {
|
||||||
statement = fmt.Sprintf(sql,
|
statement = fmt.Sprintf(sql,
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
strings.Join(colNames, session.engine.QuoteStr()+", "+session.engine.QuoteStr()),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
|
@ -240,7 +241,7 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error
|
||||||
}
|
}
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheInsert(session.statement.TableName())
|
session.cacheInsert(table, tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
lenAfterClosures := len(session.afterClosures)
|
lenAfterClosures := len(session.afterClosures)
|
||||||
|
@ -347,18 +348,19 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var sqlStr string
|
var sqlStr string
|
||||||
|
var tableName = session.statement.TableName()
|
||||||
if len(colPlaces) > 0 {
|
if len(colPlaces) > 0 {
|
||||||
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
sqlStr = fmt.Sprintf("INSERT INTO %s (%v%v%v) VALUES (%v)",
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
strings.Join(colNames, session.engine.Quote(", ")),
|
strings.Join(colNames, session.engine.Quote(", ")),
|
||||||
session.engine.QuoteStr(),
|
session.engine.QuoteStr(),
|
||||||
colPlaces)
|
colPlaces)
|
||||||
} else {
|
} else {
|
||||||
if session.engine.dialect.DBType() == core.MYSQL {
|
if session.engine.dialect.DBType() == core.MYSQL {
|
||||||
sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(session.statement.TableName()))
|
sqlStr = fmt.Sprintf("INSERT INTO %s VALUES ()", session.engine.Quote(tableName))
|
||||||
} else {
|
} else {
|
||||||
sqlStr = fmt.Sprintf("INSERT INTO %s DEFAULT VALUES", session.engine.Quote(session.statement.TableName()))
|
sqlStr = fmt.Sprintf("INSERT INTO %s DEFAULT VALUES", session.engine.Quote(tableName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,7 +403,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
handleAfterInsertProcessorFunc(bean)
|
handleAfterInsertProcessorFunc(bean)
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheInsert(session.statement.TableName())
|
session.cacheInsert(table, tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if table.Version != "" && session.statement.checkVersion {
|
if table.Version != "" && session.statement.checkVersion {
|
||||||
|
@ -446,7 +448,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
handleAfterInsertProcessorFunc(bean)
|
handleAfterInsertProcessorFunc(bean)
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheInsert(session.statement.TableName())
|
session.cacheInsert(table, tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if table.Version != "" && session.statement.checkVersion {
|
if table.Version != "" && session.statement.checkVersion {
|
||||||
|
@ -489,7 +491,7 @@ func (session *Session) innerInsert(bean interface{}) (int64, error) {
|
||||||
defer handleAfterInsertProcessorFunc(bean)
|
defer handleAfterInsertProcessorFunc(bean)
|
||||||
|
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
session.cacheInsert(session.statement.TableName())
|
session.cacheInsert(table, tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if table.Version != "" && session.statement.checkVersion {
|
if table.Version != "" && session.statement.checkVersion {
|
||||||
|
@ -537,14 +539,12 @@ func (session *Session) InsertOne(bean interface{}) (int64, error) {
|
||||||
return session.innerInsert(bean)
|
return session.innerInsert(bean)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) cacheInsert(tables ...string) error {
|
func (session *Session) cacheInsert(table *core.Table, tables ...string) error {
|
||||||
if session.statement.RefTable == nil {
|
if table == nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
table := session.statement.RefTable
|
|
||||||
cacher := session.engine.getCacher2(table)
|
cacher := session.engine.getCacher2(table)
|
||||||
|
|
||||||
for _, t := range tables {
|
for _, t := range tables {
|
||||||
session.engine.logger.Debug("[cache] clear sql:", t)
|
session.engine.logger.Debug("[cache] clear sql:", t)
|
||||||
cacher.ClearIds(t)
|
cacher.ClearIds(t)
|
||||||
|
|
|
@ -125,15 +125,15 @@ func TestInsertOneIfPkIsPoint(t *testing.T) {
|
||||||
func TestInsertOneIfPkIsPointRename(t *testing.T) {
|
func TestInsertOneIfPkIsPointRename(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
type ID *int64
|
type ID *int64
|
||||||
type TestPoint struct {
|
type TestPoint2 struct {
|
||||||
Id ID `xorm:"autoincr pk notnull 'id'"`
|
Id ID `xorm:"autoincr pk notnull 'id'"`
|
||||||
Msg *string `xorm:"varchar(255)"`
|
Msg *string `xorm:"varchar(255)"`
|
||||||
Created *time.Time `xorm:"created"`
|
Created *time.Time `xorm:"created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(TestPoint)))
|
assert.NoError(t, testEngine.Sync2(new(TestPoint2)))
|
||||||
msg := "hi"
|
msg := "hi"
|
||||||
data := TestPoint{Msg: &msg}
|
data := TestPoint2{Msg: &msg}
|
||||||
_, err := testEngine.InsertOne(&data)
|
_, err := testEngine.InsertOne(&data)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -764,21 +764,11 @@ func TestCompositeKey(t *testing.T) {
|
||||||
t.Error(errors.New("failed to insert CompositeKey{22, 22}"))
|
t.Error(errors.New("failed to insert CompositeKey{22, 22}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if testEngine.Cacher != nil {
|
|
||||||
testEngine.Cacher.ClearBeans(testEngine.TableInfo(compositeKeyVal).Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
cps = make([]CompositeKey, 0)
|
cps = make([]CompositeKey, 0)
|
||||||
err = testEngine.Find(&cps)
|
err = testEngine.Find(&cps)
|
||||||
if err != nil {
|
assert.NoError(t, err)
|
||||||
t.Error(err)
|
assert.EqualValues(t, 2, len(cps), "should has two record")
|
||||||
}
|
assert.EqualValues(t, compositeKeyVal, cps[0], "should be equeal")
|
||||||
if len(cps) != 2 {
|
|
||||||
t.Error(errors.New("should has two record"))
|
|
||||||
}
|
|
||||||
if cps[0] != compositeKeyVal {
|
|
||||||
t.Error(errors.New("should be equeal"))
|
|
||||||
}
|
|
||||||
|
|
||||||
compositeKeyVal = CompositeKey{UpdateStr: "test1"}
|
compositeKeyVal = CompositeKey{UpdateStr: "test1"}
|
||||||
cnt, err = testEngine.ID(core.PK{11, 22}).Update(&compositeKeyVal)
|
cnt, err = testEngine.ID(core.PK{11, 22}).Update(&compositeKeyVal)
|
||||||
|
@ -796,6 +786,9 @@ func TestCompositeKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCompositeKey2(t *testing.T) {
|
||||||
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
UserId string `xorm:"varchar(19) not null pk"`
|
UserId string `xorm:"varchar(19) not null pk"`
|
||||||
NickName string `xorm:"varchar(19) not null"`
|
NickName string `xorm:"varchar(19) not null"`
|
||||||
|
@ -803,9 +796,6 @@ type User struct {
|
||||||
Score int32 `xorm:"integer"`
|
Score int32 `xorm:"integer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompositeKey2(t *testing.T) {
|
|
||||||
assert.NoError(t, prepareEngine())
|
|
||||||
|
|
||||||
err := testEngine.DropTables(&User{})
|
err := testEngine.DropTables(&User{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
func TestQueryString(t *testing.T) {
|
func TestQueryString(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type GetVar struct {
|
type GetVar2 struct {
|
||||||
Id int64 `xorm:"autoincr pk"`
|
Id int64 `xorm:"autoincr pk"`
|
||||||
Msg string `xorm:"varchar(255)"`
|
Msg string `xorm:"varchar(255)"`
|
||||||
Age int
|
Age int
|
||||||
|
@ -24,9 +24,9 @@ func TestQueryString(t *testing.T) {
|
||||||
Created time.Time `xorm:"created"`
|
Created time.Time `xorm:"created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(GetVar)))
|
assert.NoError(t, testEngine.Sync2(new(GetVar2)))
|
||||||
|
|
||||||
var data = GetVar{
|
var data = GetVar2{
|
||||||
Msg: "hi",
|
Msg: "hi",
|
||||||
Age: 28,
|
Age: 28,
|
||||||
Money: 1.5,
|
Money: 1.5,
|
||||||
|
@ -34,7 +34,7 @@ func TestQueryString(t *testing.T) {
|
||||||
_, err := testEngine.InsertOne(data)
|
_, err := testEngine.InsertOne(data)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
records, err := testEngine.QueryString("select * from get_var")
|
records, err := testEngine.QueryString("select * from get_var2")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, 1, len(records))
|
assert.Equal(t, 1, len(records))
|
||||||
assert.Equal(t, 5, len(records[0]))
|
assert.Equal(t, 5, len(records[0]))
|
||||||
|
|
|
@ -197,8 +197,9 @@ func TestMetaInfo(t *testing.T) {
|
||||||
tables, err := testEngine.DBMetas()
|
tables, err := testEngine.DBMetas()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 2, len(tables))
|
assert.EqualValues(t, 2, len(tables))
|
||||||
assert.EqualValues(t, "customtablename", tables[0].Name)
|
tableNames := []string{tables[0].Name, tables[1].Name}
|
||||||
assert.EqualValues(t, "index_or_unique", tables[1].Name)
|
assert.Contains(t, tableNames, "customtablename")
|
||||||
|
assert.Contains(t, tableNames, "index_or_unique")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCharst(t *testing.T) {
|
func TestCharst(t *testing.T) {
|
||||||
|
|
|
@ -76,26 +76,26 @@ func TestSum(t *testing.T) {
|
||||||
func TestSumCustomColumn(t *testing.T) {
|
func TestSumCustomColumn(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type SumStruct struct {
|
type SumStruct2 struct {
|
||||||
Int int
|
Int int
|
||||||
Float float32
|
Float float32
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cases = []SumStruct{
|
cases = []SumStruct2{
|
||||||
{1, 6.2},
|
{1, 6.2},
|
||||||
{2, 5.3},
|
{2, 5.3},
|
||||||
{92, -0.2},
|
{92, -0.2},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(SumStruct)))
|
assert.NoError(t, testEngine.Sync2(new(SumStruct2)))
|
||||||
|
|
||||||
cnt, err := testEngine.Insert(cases)
|
cnt, err := testEngine.Insert(cases)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 3, cnt)
|
assert.EqualValues(t, 3, cnt)
|
||||||
|
|
||||||
sumInt, err := testEngine.Sum(new(SumStruct),
|
sumInt, err := testEngine.Sum(new(SumStruct2),
|
||||||
"CASE WHEN `int` <= 2 THEN `int` ELSE 0 END")
|
"CASE WHEN `int` <= 2 THEN `int` ELSE 0 END")
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 3, int(sumInt))
|
assert.EqualValues(t, 3, int(sumInt))
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
func (session *Session) cacheUpdate(table *core.Table, tableName, sqlStr string, args ...interface{}) error {
|
||||||
if session.statement.RefTable == nil ||
|
if table == nil ||
|
||||||
session.tx != nil {
|
session.tx != nil {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
for _, filter := range session.engine.dialect.Filters() {
|
for _, filter := range session.engine.dialect.Filters() {
|
||||||
newsql = filter.Do(newsql, session.engine.dialect, session.statement.RefTable)
|
newsql = filter.Do(newsql, session.engine.dialect, table)
|
||||||
}
|
}
|
||||||
session.engine.logger.Debug("[cacheUpdate] new sql", oldhead, newsql)
|
session.engine.logger.Debug("[cacheUpdate] new sql", oldhead, newsql)
|
||||||
|
|
||||||
|
@ -39,9 +39,8 @@ func (session *Session) cacheUpdate(sqlStr string, args ...interface{}) error {
|
||||||
nStart = strings.Count(oldhead, "$")
|
nStart = strings.Count(oldhead, "$")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table := session.statement.RefTable
|
|
||||||
cacher := session.engine.getCacher2(table)
|
cacher := session.engine.getCacher2(table)
|
||||||
tableName := session.statement.TableName()
|
|
||||||
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
session.engine.logger.Debug("[cacheUpdate] get cache sql", newsql, args[nStart:])
|
||||||
ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
ids, err := core.GetCacheSql(cacher, tableName, newsql, args[nStart:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -280,6 +279,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
condSQL = condSQL + fmt.Sprintf(" ORDER BY %v", st.OrderStr)
|
condSQL = condSQL + fmt.Sprintf(" ORDER BY %v", st.OrderStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var tableName = session.statement.TableName()
|
||||||
// TODO: Oracle support needed
|
// TODO: Oracle support needed
|
||||||
var top string
|
var top string
|
||||||
if st.LimitN > 0 {
|
if st.LimitN > 0 {
|
||||||
|
@ -288,7 +288,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
} else if st.Engine.dialect.DBType() == core.SQLITE {
|
} else if st.Engine.dialect.DBType() == core.SQLITE {
|
||||||
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
||||||
cond = cond.And(builder.Expr(fmt.Sprintf("rowid IN (SELECT rowid FROM %v %v)",
|
cond = cond.And(builder.Expr(fmt.Sprintf("rowid IN (SELECT rowid FROM %v %v)",
|
||||||
session.engine.Quote(session.statement.TableName()), tempCondSQL), condArgs...))
|
session.engine.Quote(tableName), tempCondSQL), condArgs...))
|
||||||
condSQL, condArgs, err = builder.ToSQL(cond)
|
condSQL, condArgs, err = builder.ToSQL(cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -299,7 +299,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
} else if st.Engine.dialect.DBType() == core.POSTGRES {
|
} else if st.Engine.dialect.DBType() == core.POSTGRES {
|
||||||
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
tempCondSQL := condSQL + fmt.Sprintf(" LIMIT %d", st.LimitN)
|
||||||
cond = cond.And(builder.Expr(fmt.Sprintf("CTID IN (SELECT CTID FROM %v %v)",
|
cond = cond.And(builder.Expr(fmt.Sprintf("CTID IN (SELECT CTID FROM %v %v)",
|
||||||
session.engine.Quote(session.statement.TableName()), tempCondSQL), condArgs...))
|
session.engine.Quote(tableName), tempCondSQL), condArgs...))
|
||||||
condSQL, condArgs, err = builder.ToSQL(cond)
|
condSQL, condArgs, err = builder.ToSQL(cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -313,7 +313,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
table != nil && len(table.PrimaryKeys) == 1 {
|
table != nil && len(table.PrimaryKeys) == 1 {
|
||||||
cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)",
|
cond = builder.Expr(fmt.Sprintf("%s IN (SELECT TOP (%d) %s FROM %v%v)",
|
||||||
table.PrimaryKeys[0], st.LimitN, table.PrimaryKeys[0],
|
table.PrimaryKeys[0], st.LimitN, table.PrimaryKeys[0],
|
||||||
session.engine.Quote(session.statement.TableName()), condSQL), condArgs...)
|
session.engine.Quote(tableName), condSQL), condArgs...)
|
||||||
|
|
||||||
condSQL, condArgs, err = builder.ToSQL(cond)
|
condSQL, condArgs, err = builder.ToSQL(cond)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -334,7 +334,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
|
|
||||||
sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v",
|
sqlStr = fmt.Sprintf("UPDATE %v%v SET %v %v",
|
||||||
top,
|
top,
|
||||||
session.engine.Quote(session.statement.TableName()),
|
session.engine.Quote(tableName),
|
||||||
strings.Join(colNames, ", "),
|
strings.Join(colNames, ", "),
|
||||||
condSQL)
|
condSQL)
|
||||||
|
|
||||||
|
@ -349,8 +349,9 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
|
|
||||||
if table != nil {
|
if table != nil {
|
||||||
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
if cacher := session.engine.getCacher2(table); cacher != nil && session.statement.UseCache {
|
||||||
cacher.ClearIds(session.statement.TableName())
|
//session.cacheUpdate(table, tableName, sqlStr, args...)
|
||||||
cacher.ClearBeans(session.statement.TableName())
|
cacher.ClearIds(tableName)
|
||||||
|
cacher.ClearBeans(tableName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +361,7 @@ func (session *Session) Update(bean interface{}, condiBean ...interface{}) (int6
|
||||||
closure(bean)
|
closure(bean)
|
||||||
}
|
}
|
||||||
if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
|
if processor, ok := interface{}(bean).(AfterUpdateProcessor); ok {
|
||||||
session.engine.logger.Debug("[event]", session.statement.TableName(), " has after update processor")
|
session.engine.logger.Debug("[event]", tableName, " has after update processor")
|
||||||
processor.AfterUpdate()
|
processor.AfterUpdate()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -43,14 +43,14 @@ func TestUpdateMap(t *testing.T) {
|
||||||
func TestUpdateLimit(t *testing.T) {
|
func TestUpdateLimit(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type UpdateTable struct {
|
type UpdateTable2 struct {
|
||||||
Id int64
|
Id int64
|
||||||
Name string
|
Name string
|
||||||
Age int
|
Age int
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, testEngine.Sync2(new(UpdateTable)))
|
assert.NoError(t, testEngine.Sync2(new(UpdateTable2)))
|
||||||
var tb = UpdateTable{
|
var tb = UpdateTable2{
|
||||||
Name: "test1",
|
Name: "test1",
|
||||||
Age: 35,
|
Age: 35,
|
||||||
}
|
}
|
||||||
|
@ -64,13 +64,13 @@ func TestUpdateLimit(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
cnt, err = testEngine.OrderBy("name desc").Limit(1).Update(&UpdateTable{
|
cnt, err = testEngine.OrderBy("name desc").Limit(1).Update(&UpdateTable2{
|
||||||
Age: 30,
|
Age: 30,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
var uts []UpdateTable
|
var uts []UpdateTable2
|
||||||
err = testEngine.Find(&uts)
|
err = testEngine.Find(&uts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 2, len(uts))
|
assert.EqualValues(t, 2, len(uts))
|
||||||
|
|
|
@ -1205,7 +1205,8 @@ func (statement *Statement) convertIDSQL(sqlStr string) string {
|
||||||
top = fmt.Sprintf("TOP %d ", statement.LimitN)
|
top = fmt.Sprintf("TOP %d ", statement.LimitN)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1])
|
newsql := fmt.Sprintf("SELECT %s%s FROM %v", top, colstrs, sqls[1])
|
||||||
|
return newsql
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=mssql -conn_str="server=192.168.1.58;user id=sa;password=123456;database=xorm_test" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=mymysql -conn_str="xorm_test/root/" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=mysql -conn_str="root:@/xorm_test" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=postgres -conn_str="dbname=xorm_test sslmode=disable" -cache=true
|
|
@ -0,0 +1 @@
|
||||||
|
go test -db=sqlite3 -conn_str="./test.db?cache=shared&mode=rwc" -cache=true
|
64
time_test.go
64
time_test.go
|
@ -52,14 +52,14 @@ func TestTimeUserTimeDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testEngine.DatabaseTZ = dbLoc
|
testEngine.DatabaseTZ = dbLoc
|
||||||
|
|
||||||
type TimeUser struct {
|
type TimeUser2 struct {
|
||||||
Id string
|
Id string
|
||||||
OperTime time.Time
|
OperTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(TimeUser))
|
assertSync(t, new(TimeUser2))
|
||||||
|
|
||||||
var user = TimeUser{
|
var user = TimeUser2{
|
||||||
Id: "lunny",
|
Id: "lunny",
|
||||||
OperTime: time.Now(),
|
OperTime: time.Now(),
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func TestTimeUserTimeDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
var user2 TimeUser
|
var user2 TimeUser2
|
||||||
has, err := testEngine.Get(&user2)
|
has, err := testEngine.Get(&user2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -117,14 +117,14 @@ func TestTimeUserCreatedDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testEngine.DatabaseTZ = dbLoc
|
testEngine.DatabaseTZ = dbLoc
|
||||||
|
|
||||||
type UserCreated struct {
|
type UserCreated2 struct {
|
||||||
Id string
|
Id string
|
||||||
CreatedAt time.Time `xorm:"created"`
|
CreatedAt time.Time `xorm:"created"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(UserCreated))
|
assertSync(t, new(UserCreated2))
|
||||||
|
|
||||||
var user = UserCreated{
|
var user = UserCreated2{
|
||||||
Id: "lunny",
|
Id: "lunny",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ func TestTimeUserCreatedDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
var user2 UserCreated
|
var user2 UserCreated2
|
||||||
has, err := testEngine.Get(&user2)
|
has, err := testEngine.Get(&user2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -203,15 +203,15 @@ func TestTimeUserUpdatedDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testEngine.DatabaseTZ = dbLoc
|
testEngine.DatabaseTZ = dbLoc
|
||||||
|
|
||||||
type UserUpdated struct {
|
type UserUpdated2 struct {
|
||||||
Id string
|
Id string
|
||||||
CreatedAt time.Time `xorm:"created"`
|
CreatedAt time.Time `xorm:"created"`
|
||||||
UpdatedAt time.Time `xorm:"updated"`
|
UpdatedAt time.Time `xorm:"updated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(UserUpdated))
|
assertSync(t, new(UserUpdated2))
|
||||||
|
|
||||||
var user = UserUpdated{
|
var user = UserUpdated2{
|
||||||
Id: "lunny",
|
Id: "lunny",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ func TestTimeUserUpdatedDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
|
|
||||||
var user2 UserUpdated
|
var user2 UserUpdated2
|
||||||
has, err := testEngine.Get(&user2)
|
has, err := testEngine.Get(&user2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -231,7 +231,7 @@ func TestTimeUserUpdatedDiffLoc(t *testing.T) {
|
||||||
assert.EqualValues(t, formatTime(user.UpdatedAt), formatTime(user2.UpdatedAt))
|
assert.EqualValues(t, formatTime(user.UpdatedAt), formatTime(user2.UpdatedAt))
|
||||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt)
|
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt)
|
||||||
|
|
||||||
var user3 = UserUpdated{
|
var user3 = UserUpdated2{
|
||||||
Id: "lunny2",
|
Id: "lunny2",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ func TestTimeUserUpdatedDiffLoc(t *testing.T) {
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
assert.True(t, user.UpdatedAt.Unix() <= user3.UpdatedAt.Unix())
|
assert.True(t, user.UpdatedAt.Unix() <= user3.UpdatedAt.Unix())
|
||||||
|
|
||||||
var user4 UserUpdated
|
var user4 UserUpdated2
|
||||||
has, err = testEngine.Get(&user4)
|
has, err = testEngine.Get(&user4)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -307,16 +307,16 @@ func TestTimeUserDeletedDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testEngine.DatabaseTZ = dbLoc
|
testEngine.DatabaseTZ = dbLoc
|
||||||
|
|
||||||
type UserDeleted struct {
|
type UserDeleted2 struct {
|
||||||
Id string
|
Id string
|
||||||
CreatedAt time.Time `xorm:"created"`
|
CreatedAt time.Time `xorm:"created"`
|
||||||
UpdatedAt time.Time `xorm:"updated"`
|
UpdatedAt time.Time `xorm:"updated"`
|
||||||
DeletedAt time.Time `xorm:"deleted"`
|
DeletedAt time.Time `xorm:"deleted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(UserDeleted))
|
assertSync(t, new(UserDeleted2))
|
||||||
|
|
||||||
var user = UserDeleted{
|
var user = UserDeleted2{
|
||||||
Id: "lunny",
|
Id: "lunny",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ func TestTimeUserDeletedDiffLoc(t *testing.T) {
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||||
|
|
||||||
var user2 UserDeleted
|
var user2 UserDeleted2
|
||||||
has, err := testEngine.Get(&user2)
|
has, err := testEngine.Get(&user2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -336,13 +336,13 @@ func TestTimeUserDeletedDiffLoc(t *testing.T) {
|
||||||
assert.True(t, isTimeZero(user2.DeletedAt))
|
assert.True(t, isTimeZero(user2.DeletedAt))
|
||||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||||
|
|
||||||
var user3 UserDeleted
|
var user3 UserDeleted2
|
||||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
assert.True(t, !isTimeZero(user3.DeletedAt))
|
assert.True(t, !isTimeZero(user3.DeletedAt))
|
||||||
|
|
||||||
var user4 UserDeleted
|
var user4 UserDeleted2
|
||||||
has, err = testEngine.Unscoped().Get(&user4)
|
has, err = testEngine.Unscoped().Get(&user4)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -378,16 +378,16 @@ func (j *JsonDate) Unix() int64 {
|
||||||
func TestCustomTimeUserDeleted(t *testing.T) {
|
func TestCustomTimeUserDeleted(t *testing.T) {
|
||||||
assert.NoError(t, prepareEngine())
|
assert.NoError(t, prepareEngine())
|
||||||
|
|
||||||
type UserDeleted struct {
|
type UserDeleted3 struct {
|
||||||
Id string
|
Id string
|
||||||
CreatedAt JsonDate `xorm:"created"`
|
CreatedAt JsonDate `xorm:"created"`
|
||||||
UpdatedAt JsonDate `xorm:"updated"`
|
UpdatedAt JsonDate `xorm:"updated"`
|
||||||
DeletedAt JsonDate `xorm:"deleted"`
|
DeletedAt JsonDate `xorm:"deleted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(UserDeleted))
|
assertSync(t, new(UserDeleted3))
|
||||||
|
|
||||||
var user = UserDeleted{
|
var user = UserDeleted3{
|
||||||
Id: "lunny",
|
Id: "lunny",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ func TestCustomTimeUserDeleted(t *testing.T) {
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||||
|
|
||||||
var user2 UserDeleted
|
var user2 UserDeleted3
|
||||||
has, err := testEngine.Get(&user2)
|
has, err := testEngine.Get(&user2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -407,13 +407,13 @@ func TestCustomTimeUserDeleted(t *testing.T) {
|
||||||
assert.True(t, isTimeZero(time.Time(user2.DeletedAt)))
|
assert.True(t, isTimeZero(time.Time(user2.DeletedAt)))
|
||||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||||
|
|
||||||
var user3 UserDeleted
|
var user3 UserDeleted3
|
||||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
assert.True(t, !isTimeZero(time.Time(user3.DeletedAt)))
|
assert.True(t, !isTimeZero(time.Time(user3.DeletedAt)))
|
||||||
|
|
||||||
var user4 UserDeleted
|
var user4 UserDeleted3
|
||||||
has, err = testEngine.Unscoped().Get(&user4)
|
has, err = testEngine.Unscoped().Get(&user4)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -431,16 +431,16 @@ func TestCustomTimeUserDeletedDiffLoc(t *testing.T) {
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
testEngine.DatabaseTZ = dbLoc
|
testEngine.DatabaseTZ = dbLoc
|
||||||
|
|
||||||
type UserDeleted struct {
|
type UserDeleted4 struct {
|
||||||
Id string
|
Id string
|
||||||
CreatedAt JsonDate `xorm:"created"`
|
CreatedAt JsonDate `xorm:"created"`
|
||||||
UpdatedAt JsonDate `xorm:"updated"`
|
UpdatedAt JsonDate `xorm:"updated"`
|
||||||
DeletedAt JsonDate `xorm:"deleted"`
|
DeletedAt JsonDate `xorm:"deleted"`
|
||||||
}
|
}
|
||||||
|
|
||||||
assertSync(t, new(UserDeleted))
|
assertSync(t, new(UserDeleted4))
|
||||||
|
|
||||||
var user = UserDeleted{
|
var user = UserDeleted4{
|
||||||
Id: "lunny",
|
Id: "lunny",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +449,7 @@ func TestCustomTimeUserDeletedDiffLoc(t *testing.T) {
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
fmt.Println("user", user.CreatedAt, user.UpdatedAt, user.DeletedAt)
|
||||||
|
|
||||||
var user2 UserDeleted
|
var user2 UserDeleted4
|
||||||
has, err := testEngine.Get(&user2)
|
has, err := testEngine.Get(&user2)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
@ -460,13 +460,13 @@ func TestCustomTimeUserDeletedDiffLoc(t *testing.T) {
|
||||||
assert.True(t, isTimeZero(time.Time(user2.DeletedAt)))
|
assert.True(t, isTimeZero(time.Time(user2.DeletedAt)))
|
||||||
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
fmt.Println("user2", user2.CreatedAt, user2.UpdatedAt, user2.DeletedAt)
|
||||||
|
|
||||||
var user3 UserDeleted
|
var user3 UserDeleted4
|
||||||
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
cnt, err = testEngine.Where("id = ?", "lunny").Delete(&user3)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.EqualValues(t, 1, cnt)
|
assert.EqualValues(t, 1, cnt)
|
||||||
assert.True(t, !isTimeZero(time.Time(user3.DeletedAt)))
|
assert.True(t, !isTimeZero(time.Time(user3.DeletedAt)))
|
||||||
|
|
||||||
var user4 UserDeleted
|
var user4 UserDeleted4
|
||||||
has, err = testEngine.Unscoped().Get(&user4)
|
has, err = testEngine.Unscoped().Get(&user4)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.True(t, has)
|
assert.True(t, has)
|
||||||
|
|
15
xorm_test.go
15
xorm_test.go
|
@ -37,6 +37,21 @@ func createEngine(dbType, connStr string) error {
|
||||||
|
|
||||||
testEngine.ShowSQL(*showSQL)
|
testEngine.ShowSQL(*showSQL)
|
||||||
testEngine.logger.SetLevel(core.LOG_DEBUG)
|
testEngine.logger.SetLevel(core.LOG_DEBUG)
|
||||||
|
if *cache {
|
||||||
|
cacher := NewLRUCacher(NewMemoryStore(), 100000)
|
||||||
|
testEngine.SetDefaultCacher(cacher)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(*mapType) > 0 {
|
||||||
|
switch *mapType {
|
||||||
|
case "snake":
|
||||||
|
testEngine.SetMapper(core.SnakeMapper{})
|
||||||
|
case "same":
|
||||||
|
testEngine.SetMapper(core.SameMapper{})
|
||||||
|
case "gonic":
|
||||||
|
testEngine.SetMapper(core.LintGonicMapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tables, err := testEngine.DBMetas()
|
tables, err := testEngine.DBMetas()
|
||||||
|
|
Loading…
Reference in New Issue