cache bug fixed
This commit is contained in:
parent
22ddfa9f77
commit
9d676ebddd
|
@ -170,6 +170,14 @@ type User struct {
|
|||
|
||||
- 3.支持`type MyString string`等自定义的field,支持Slice, Map等field成员,这些成员默认存储为Text类型,并且默认将使用Json格式来序列化和反序列化。也支持数据库字段类型为Blob类型,如果是Blob类型,则先使用Jsong格式序列化再转成[]byte格式。当然[]byte或者[]uint8默认为Blob类型并且都已二进制方式存储。
|
||||
|
||||
- 4.实现了Conversion接口的类型或者结构体,将根据接口的转换方式在类型和数据库记录之间进行相互转换。
|
||||
```Go
|
||||
type Conversion interface {
|
||||
FromDB([]byte) error
|
||||
ToDB() ([]byte, error)
|
||||
}
|
||||
```
|
||||
|
||||
<a name="30" id="30"></a>
|
||||
## 3.创建表
|
||||
|
||||
|
|
16
README_CN.md
16
README_CN.md
|
@ -7,6 +7,7 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
|||
[](https://drone.io/github.com/lunny/xorm/latest)
|
||||
|
||||
## 讨论
|
||||
|
||||
请加入QQ群:280360085 进行讨论。
|
||||
|
||||
## 驱动支持
|
||||
|
@ -55,14 +56,15 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
|||
|
||||
go get github.com/lunny/xorm
|
||||
|
||||
## 快速开始
|
||||
|
||||
请访问 [快速开始](https://github.com/lunny/xorm/blob/master/QuickStart.md) 查看详细文档
|
||||
|
||||
|
||||
## 文档
|
||||
|
||||
请访问 [GoWalker](http://gowalker.org/github.com/lunny/xorm) 查看详细文档
|
||||
* [快速开始](https://github.com/lunny/xorm/blob/master/QuickStart.md)
|
||||
|
||||
* [GoWalker代码文档](http://gowalker.org/github.com/lunny/xorm)
|
||||
|
||||
## 案例
|
||||
|
||||
* [Godaily.org](http://godaily.org)
|
||||
|
||||
## FAQ
|
||||
|
||||
|
@ -75,6 +77,8 @@ type User struct {
|
|||
Name string `json:"name" xorm:"name"`
|
||||
}
|
||||
```
|
||||
2.问:xorm有几种命名映射规则?
|
||||
答案:目前支持SnakeMapper和SameMapper两种。SnakeMapper支持结构体和成员以驼峰式命名而数据库表和字段以下划线连接命名;SameMapper支持结构体和数据库的命名保持一致的映射。
|
||||
|
||||
## LICENSE
|
||||
|
||||
|
|
6
cache.go
6
cache.go
|
@ -18,7 +18,7 @@ type CacheStore interface {
|
|||
|
||||
type MemoryStore struct {
|
||||
store map[interface{}]interface{}
|
||||
mutex sync.Mutex
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewMemoryStore() *MemoryStore {
|
||||
|
@ -34,8 +34,8 @@ func (s *MemoryStore) Put(key, value interface{}) error {
|
|||
}
|
||||
|
||||
func (s *MemoryStore) Get(key interface{}) (interface{}, error) {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
s.mutex.Rlock()
|
||||
defer s.mutex.UnRlock()
|
||||
//fmt.Println("before get store:", s.store)
|
||||
if v, ok := s.store[key]; ok {
|
||||
return v, nil
|
||||
|
|
68
session.go
68
session.go
|
@ -392,13 +392,14 @@ func (session *Session) cacheGet(bean interface{}, sql string, args ...interface
|
|||
|
||||
cacher := session.Statement.RefTable.Cacher
|
||||
tableName := session.Statement.TableName()
|
||||
session.Engine.LogDebug("[xorm:cacheGet] find sql:", newsql, args)
|
||||
ids, err := getCacheSql(cacher, tableName, newsql, args)
|
||||
if err != nil {
|
||||
resultsSlice, err := session.query(newsql, args...)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
session.Engine.LogDebug("[xorm:cacheGet] query ids:", resultsSlice)
|
||||
ids = make([]int64, 0)
|
||||
if len(resultsSlice) > 0 {
|
||||
data := resultsSlice[0]
|
||||
|
@ -413,19 +414,19 @@ func (session *Session) cacheGet(bean interface{}, sql string, args ...interface
|
|||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
session.Engine.LogDebug("[xorm:cache] cache ids:", newsql, ids)
|
||||
session.Engine.LogDebug("[xorm:cacheGet] cache ids:", newsql, ids)
|
||||
err = putCacheSql(cacher, ids, tableName, newsql, args)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
} else {
|
||||
session.Engine.LogDebug("[xorm:cache] cached sql:", newsql)
|
||||
session.Engine.LogDebug("[xorm:cacheGet] cached sql:", newsql)
|
||||
}
|
||||
|
||||
if len(ids) > 0 {
|
||||
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
id := ids[0]
|
||||
|
||||
session.Engine.LogDebug("[xorm:cacheGet] get bean:", tableName, id)
|
||||
cacheBean := cacher.GetBean(tableName, id)
|
||||
if cacheBean == nil {
|
||||
newSession := session.Engine.NewSession()
|
||||
|
@ -436,10 +437,10 @@ func (session *Session) cacheGet(bean interface{}, sql string, args ...interface
|
|||
return has, err
|
||||
}
|
||||
|
||||
session.Engine.LogDebug("[xorm:cache] cache bean:", tableName, id, cacheBean)
|
||||
session.Engine.LogDebug("[xorm:cacheGet] cache bean:", tableName, id, cacheBean)
|
||||
cacher.PutBean(tableName, id, cacheBean)
|
||||
} else {
|
||||
session.Engine.LogDebug("[xorm:cache] cached bean:", tableName, id, cacheBean)
|
||||
session.Engine.LogDebug("[xorm:cacheGet] cached bean:", tableName, id, cacheBean)
|
||||
has = true
|
||||
}
|
||||
structValue.Set(reflect.Indirect(reflect.ValueOf(cacheBean)))
|
||||
|
@ -474,7 +475,7 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
|||
}
|
||||
// 查询数目太大,采用缓存将不是一个很好的方式。
|
||||
if len(resultsSlice) > 100 {
|
||||
session.Engine.LogDebug("[xorm:cache] ids > 100, no cache")
|
||||
session.Engine.LogDebug("[xorm:cacheFind] ids > 100, no cache")
|
||||
return ErrCacheFailed
|
||||
}
|
||||
|
||||
|
@ -495,13 +496,13 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
|||
ids = append(ids, id)
|
||||
}
|
||||
}
|
||||
session.Engine.LogDebug("[xorm:cache] cache ids:", ids, tableName, newsql, args)
|
||||
session.Engine.LogDebug("[xorm:cacheFind] cache ids:", ids, tableName, newsql, args)
|
||||
err = putCacheSql(cacher, ids, tableName, newsql, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
session.Engine.LogDebug("[xorm:cache] cached sql:", newsql, args)
|
||||
session.Engine.LogDebug("[xorm:cacheFind] cached sql:", newsql, args)
|
||||
}
|
||||
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(rowsSlicePtr))
|
||||
|
@ -515,7 +516,7 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
|||
idxes = append(idxes, idx)
|
||||
ides = append(ides, id)
|
||||
} else {
|
||||
session.Engine.LogDebug("[xorm:cache] cached bean:", tableName, id, bean)
|
||||
session.Engine.LogDebug("[xorm:cacheFind] cached bean:", tableName, id, bean)
|
||||
temps[idx] = bean
|
||||
}
|
||||
}
|
||||
|
@ -534,7 +535,7 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
|||
for i := 0; i < vs.Len(); i++ {
|
||||
bean := vs.Index(i).Addr().Interface()
|
||||
temps[idxes[i]] = bean
|
||||
session.Engine.LogDebug("[xorm:cache] cache bean:", tableName, ides[i], bean)
|
||||
session.Engine.LogDebug("[xorm:cacheFind] cache bean:", tableName, ides[i], bean)
|
||||
cacher.PutBean(tableName, ides[i].(int64), bean)
|
||||
}
|
||||
}
|
||||
|
@ -544,13 +545,11 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
|||
if bean != nil {
|
||||
sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(bean))))
|
||||
} else {
|
||||
session.Engine.LogDebug("[xorm:cache] cache delete:", tableName, ides[j])
|
||||
session.Engine.LogDebug("[xorm:cacheFind] cache delete:", tableName, ides[j])
|
||||
cacher.DelBean(tableName, ids[j])
|
||||
|
||||
session.Engine.LogDebug("[xorm:cache] cache clear:", tableName)
|
||||
fmt.Println(cacher)
|
||||
session.Engine.LogDebug("[xorm:cacheFind] cache clear:", tableName)
|
||||
cacher.ClearIds(tableName)
|
||||
fmt.Println(cacher)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -595,10 +594,7 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
|||
return false, nil
|
||||
}
|
||||
|
||||
results := resultsSlice[0]
|
||||
|
||||
err = session.scanMapIntoStruct(bean, results)
|
||||
|
||||
err = session.scanMapIntoStruct(bean, resultsSlice[0])
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
@ -1311,14 +1307,26 @@ func (statement *Statement) convertUpdateSql(sql string) (string, string) {
|
|||
if statement.RefTable == nil || statement.RefTable.PrimaryKey == "" {
|
||||
return "", ""
|
||||
}
|
||||
sqls := strings.SplitN(strings.ToLower(sql), "where", 2)
|
||||
idx := strings.Index(strings.ToLower(sql), "where")
|
||||
sqls := strings.SplitN(sql, sql[idx:idx+5], 2)
|
||||
if len(sqls) != 2 {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
var whereStr = sqls[1]
|
||||
//TODO: for postgres only, if any other database?
|
||||
if strings.Contains(sqls[1], "$") {
|
||||
dollers := strings.Split(sqls[1], "$")
|
||||
whereStr = dollers[0]
|
||||
for i, c := range dollers[1:] {
|
||||
ccs := strings.SplitN(c, " ", 2)
|
||||
whereStr += fmt.Sprintf("$%v %v", i+1, ccs[1])
|
||||
}
|
||||
}
|
||||
|
||||
return sqls[0], fmt.Sprintf("SELECT %v FROM %v WHERE %v",
|
||||
statement.Engine.Quote(statement.RefTable.PrimaryKey), statement.Engine.Quote(statement.TableName()),
|
||||
sqls[1])
|
||||
whereStr)
|
||||
}
|
||||
|
||||
func (session *Session) cacheInsert(tables ...string) error {
|
||||
|
@ -1342,14 +1350,14 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
|||
return ErrCacheFailed
|
||||
}
|
||||
|
||||
for _, filter := range session.Engine.Filters {
|
||||
sql = filter.Do(sql, session)
|
||||
}
|
||||
|
||||
oldhead, newsql := session.Statement.convertUpdateSql(sql)
|
||||
if newsql == "" {
|
||||
return ErrCacheFailed
|
||||
}
|
||||
for _, filter := range session.Engine.Filters {
|
||||
newsql = filter.Do(newsql, session)
|
||||
}
|
||||
session.Engine.LogDebug("[xorm:cacheUpdate] new sql", oldhead, newsql)
|
||||
|
||||
var nStart int
|
||||
if len(args) > 0 {
|
||||
|
@ -1363,12 +1371,15 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
|||
table := session.Statement.RefTable
|
||||
cacher := table.Cacher
|
||||
tableName := session.Statement.TableName()
|
||||
ids, err := getCacheSql(cacher, tableName, newsql, args)
|
||||
session.Engine.LogDebug("[xorm:cacheUpdate] get cache sql", newsql, args[nStart:])
|
||||
ids, err := getCacheSql(cacher, tableName, newsql, args[nStart:])
|
||||
if err != nil {
|
||||
resultsSlice, err := session.query(newsql, args[nStart:]...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
session.Engine.LogDebug("[xorm:cacheUpdate] find updated id", resultsSlice)
|
||||
|
||||
ids = make([]int64, 0)
|
||||
if len(resultsSlice) > 0 {
|
||||
for _, data := range resultsSlice {
|
||||
|
@ -1385,7 +1396,7 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
session.Engine.LogDebug("[xorm:cache] del cached sql:", tableName, newsql, args)
|
||||
session.Engine.LogDebug("[xorm:cacheUpdate] del cached sql:", tableName, newsql, args)
|
||||
cacher.DelIds(tableName, genSqlKey(newsql, args))
|
||||
}
|
||||
|
||||
|
@ -1410,13 +1421,16 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
|||
colName = strings.TrimSpace(strings.Replace(colName, session.Engine.QuoteStr(), "", -1))
|
||||
}
|
||||
//fmt.Println("find", colName)
|
||||
|
||||
if col, ok := table.Columns[colName]; ok {
|
||||
fieldValue := col.ValueOf(bean)
|
||||
session.Engine.LogDebug("[xorm:cacheUpdate] set bean field", bean, colName, fieldValue.Interface())
|
||||
//session.bytes2Value(col, fieldValue, []byte(args[idx]))
|
||||
fieldValue.Set(reflect.ValueOf(args[idx]))
|
||||
}
|
||||
}
|
||||
|
||||
session.Engine.LogDebug("[xorm:cacheUpdate] update cache", tableName, id, bean)
|
||||
cacher.PutBean(tableName, id, bean)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue