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类型并且都已二进制方式存储。
|
- 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>
|
<a name="30" id="30"></a>
|
||||||
## 3.创建表
|
## 3.创建表
|
||||||
|
|
||||||
|
|
18
README_CN.md
18
README_CN.md
|
@ -7,6 +7,7 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||||
[](https://drone.io/github.com/lunny/xorm/latest)
|
[](https://drone.io/github.com/lunny/xorm/latest)
|
||||||
|
|
||||||
## 讨论
|
## 讨论
|
||||||
|
|
||||||
请加入QQ群:280360085 进行讨论。
|
请加入QQ群:280360085 进行讨论。
|
||||||
|
|
||||||
## 驱动支持
|
## 驱动支持
|
||||||
|
@ -48,21 +49,22 @@ xorm是一个简单而强大的Go语言ORM库. 通过它可以使数据库操作
|
||||||
|
|
||||||
* 支持数据库连接池
|
* 支持数据库连接池
|
||||||
|
|
||||||
* 支持级联加载struct
|
* 支持级联加载struct
|
||||||
|
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
go get github.com/lunny/xorm
|
go get github.com/lunny/xorm
|
||||||
|
|
||||||
## 快速开始
|
|
||||||
|
|
||||||
请访问 [快速开始](https://github.com/lunny/xorm/blob/master/QuickStart.md) 查看详细文档
|
|
||||||
|
|
||||||
|
|
||||||
## 文档
|
## 文档
|
||||||
|
|
||||||
|
* [快速开始](https://github.com/lunny/xorm/blob/master/QuickStart.md)
|
||||||
|
|
||||||
请访问 [GoWalker](http://gowalker.org/github.com/lunny/xorm) 查看详细文档
|
* [GoWalker代码文档](http://gowalker.org/github.com/lunny/xorm)
|
||||||
|
|
||||||
|
## 案例
|
||||||
|
|
||||||
|
* [Godaily.org](http://godaily.org)
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
@ -75,6 +77,8 @@ type User struct {
|
||||||
Name string `json:"name" xorm:"name"`
|
Name string `json:"name" xorm:"name"`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
2.问:xorm有几种命名映射规则?
|
||||||
|
答案:目前支持SnakeMapper和SameMapper两种。SnakeMapper支持结构体和成员以驼峰式命名而数据库表和字段以下划线连接命名;SameMapper支持结构体和数据库的命名保持一致的映射。
|
||||||
|
|
||||||
## LICENSE
|
## LICENSE
|
||||||
|
|
||||||
|
|
6
cache.go
6
cache.go
|
@ -18,7 +18,7 @@ type CacheStore interface {
|
||||||
|
|
||||||
type MemoryStore struct {
|
type MemoryStore struct {
|
||||||
store map[interface{}]interface{}
|
store map[interface{}]interface{}
|
||||||
mutex sync.Mutex
|
mutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMemoryStore() *MemoryStore {
|
func NewMemoryStore() *MemoryStore {
|
||||||
|
@ -34,8 +34,8 @@ func (s *MemoryStore) Put(key, value interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MemoryStore) Get(key interface{}) (interface{}, error) {
|
func (s *MemoryStore) Get(key interface{}) (interface{}, error) {
|
||||||
s.mutex.Lock()
|
s.mutex.Rlock()
|
||||||
defer s.mutex.Unlock()
|
defer s.mutex.UnRlock()
|
||||||
//fmt.Println("before get store:", s.store)
|
//fmt.Println("before get store:", s.store)
|
||||||
if v, ok := s.store[key]; ok {
|
if v, ok := s.store[key]; ok {
|
||||||
return v, nil
|
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
|
cacher := session.Statement.RefTable.Cacher
|
||||||
tableName := session.Statement.TableName()
|
tableName := session.Statement.TableName()
|
||||||
|
session.Engine.LogDebug("[xorm:cacheGet] find sql:", newsql, args)
|
||||||
ids, err := getCacheSql(cacher, tableName, newsql, args)
|
ids, err := getCacheSql(cacher, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resultsSlice, err := session.query(newsql, args...)
|
resultsSlice, err := session.query(newsql, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
session.Engine.LogDebug("[xorm:cacheGet] query ids:", resultsSlice)
|
||||||
ids = make([]int64, 0)
|
ids = make([]int64, 0)
|
||||||
if len(resultsSlice) > 0 {
|
if len(resultsSlice) > 0 {
|
||||||
data := resultsSlice[0]
|
data := resultsSlice[0]
|
||||||
|
@ -413,19 +414,19 @@ func (session *Session) cacheGet(bean interface{}, sql string, args ...interface
|
||||||
}
|
}
|
||||||
ids = append(ids, id)
|
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)
|
err = putCacheSql(cacher, ids, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session.Engine.LogDebug("[xorm:cache] cached sql:", newsql)
|
session.Engine.LogDebug("[xorm:cacheGet] cached sql:", newsql)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(ids) > 0 {
|
if len(ids) > 0 {
|
||||||
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
structValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||||
id := ids[0]
|
id := ids[0]
|
||||||
|
session.Engine.LogDebug("[xorm:cacheGet] get bean:", tableName, id)
|
||||||
cacheBean := cacher.GetBean(tableName, id)
|
cacheBean := cacher.GetBean(tableName, id)
|
||||||
if cacheBean == nil {
|
if cacheBean == nil {
|
||||||
newSession := session.Engine.NewSession()
|
newSession := session.Engine.NewSession()
|
||||||
|
@ -436,10 +437,10 @@ func (session *Session) cacheGet(bean interface{}, sql string, args ...interface
|
||||||
return has, err
|
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)
|
cacher.PutBean(tableName, id, cacheBean)
|
||||||
} else {
|
} else {
|
||||||
session.Engine.LogDebug("[xorm:cache] cached bean:", tableName, id, cacheBean)
|
session.Engine.LogDebug("[xorm:cacheGet] cached bean:", tableName, id, cacheBean)
|
||||||
has = true
|
has = true
|
||||||
}
|
}
|
||||||
structValue.Set(reflect.Indirect(reflect.ValueOf(cacheBean)))
|
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 {
|
if len(resultsSlice) > 100 {
|
||||||
session.Engine.LogDebug("[xorm:cache] ids > 100, no cache")
|
session.Engine.LogDebug("[xorm:cacheFind] ids > 100, no cache")
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,13 +496,13 @@ func (session *Session) cacheFind(t reflect.Type, sql string, rowsSlicePtr inter
|
||||||
ids = append(ids, id)
|
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)
|
err = putCacheSql(cacher, ids, tableName, newsql, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} 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))
|
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)
|
idxes = append(idxes, idx)
|
||||||
ides = append(ides, id)
|
ides = append(ides, id)
|
||||||
} else {
|
} else {
|
||||||
session.Engine.LogDebug("[xorm:cache] cached bean:", tableName, id, bean)
|
session.Engine.LogDebug("[xorm:cacheFind] cached bean:", tableName, id, bean)
|
||||||
temps[idx] = 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++ {
|
for i := 0; i < vs.Len(); i++ {
|
||||||
bean := vs.Index(i).Addr().Interface()
|
bean := vs.Index(i).Addr().Interface()
|
||||||
temps[idxes[i]] = bean
|
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)
|
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 {
|
if bean != nil {
|
||||||
sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(bean))))
|
sliceValue.Set(reflect.Append(sliceValue, reflect.Indirect(reflect.ValueOf(bean))))
|
||||||
} else {
|
} 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])
|
cacher.DelBean(tableName, ids[j])
|
||||||
|
|
||||||
session.Engine.LogDebug("[xorm:cache] cache clear:", tableName)
|
session.Engine.LogDebug("[xorm:cacheFind] cache clear:", tableName)
|
||||||
fmt.Println(cacher)
|
|
||||||
cacher.ClearIds(tableName)
|
cacher.ClearIds(tableName)
|
||||||
fmt.Println(cacher)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,10 +594,7 @@ func (session *Session) Get(bean interface{}) (bool, error) {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
results := resultsSlice[0]
|
err = session.scanMapIntoStruct(bean, resultsSlice[0])
|
||||||
|
|
||||||
err = session.scanMapIntoStruct(bean, results)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
@ -1311,14 +1307,26 @@ func (statement *Statement) convertUpdateSql(sql string) (string, string) {
|
||||||
if statement.RefTable == nil || statement.RefTable.PrimaryKey == "" {
|
if statement.RefTable == nil || statement.RefTable.PrimaryKey == "" {
|
||||||
return "", ""
|
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 {
|
if len(sqls) != 2 {
|
||||||
return "", ""
|
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",
|
return sqls[0], fmt.Sprintf("SELECT %v FROM %v WHERE %v",
|
||||||
statement.Engine.Quote(statement.RefTable.PrimaryKey), statement.Engine.Quote(statement.TableName()),
|
statement.Engine.Quote(statement.RefTable.PrimaryKey), statement.Engine.Quote(statement.TableName()),
|
||||||
sqls[1])
|
whereStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) cacheInsert(tables ...string) error {
|
func (session *Session) cacheInsert(tables ...string) error {
|
||||||
|
@ -1342,14 +1350,14 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
||||||
return ErrCacheFailed
|
return ErrCacheFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, filter := range session.Engine.Filters {
|
|
||||||
sql = filter.Do(sql, session)
|
|
||||||
}
|
|
||||||
|
|
||||||
oldhead, newsql := session.Statement.convertUpdateSql(sql)
|
oldhead, newsql := session.Statement.convertUpdateSql(sql)
|
||||||
if newsql == "" {
|
if newsql == "" {
|
||||||
return ErrCacheFailed
|
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
|
var nStart int
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
|
@ -1363,12 +1371,15 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
||||||
table := session.Statement.RefTable
|
table := session.Statement.RefTable
|
||||||
cacher := table.Cacher
|
cacher := table.Cacher
|
||||||
tableName := session.Statement.TableName()
|
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 {
|
if err != nil {
|
||||||
resultsSlice, err := session.query(newsql, args[nStart:]...)
|
resultsSlice, err := session.query(newsql, args[nStart:]...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
session.Engine.LogDebug("[xorm:cacheUpdate] find updated id", resultsSlice)
|
||||||
|
|
||||||
ids = make([]int64, 0)
|
ids = make([]int64, 0)
|
||||||
if len(resultsSlice) > 0 {
|
if len(resultsSlice) > 0 {
|
||||||
for _, data := range resultsSlice {
|
for _, data := range resultsSlice {
|
||||||
|
@ -1385,7 +1396,7 @@ func (session *Session) cacheUpdate(sql string, args ...interface{}) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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))
|
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))
|
colName = strings.TrimSpace(strings.Replace(colName, session.Engine.QuoteStr(), "", -1))
|
||||||
}
|
}
|
||||||
//fmt.Println("find", colName)
|
//fmt.Println("find", colName)
|
||||||
|
|
||||||
if col, ok := table.Columns[colName]; ok {
|
if col, ok := table.Columns[colName]; ok {
|
||||||
fieldValue := col.ValueOf(bean)
|
fieldValue := col.ValueOf(bean)
|
||||||
|
session.Engine.LogDebug("[xorm:cacheUpdate] set bean field", bean, colName, fieldValue.Interface())
|
||||||
//session.bytes2Value(col, fieldValue, []byte(args[idx]))
|
//session.bytes2Value(col, fieldValue, []byte(args[idx]))
|
||||||
fieldValue.Set(reflect.ValueOf(args[idx]))
|
fieldValue.Set(reflect.ValueOf(args[idx]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.Engine.LogDebug("[xorm:cacheUpdate] update cache", tableName, id, bean)
|
||||||
cacher.PutBean(tableName, id, bean)
|
cacher.PutBean(tableName, id, bean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue