From b9d6ac26d1e5f3b8943a3af4b0c692ca09af0008 Mon Sep 17 00:00:00 2001 From: John Guo Date: Fri, 17 Dec 2021 11:46:05 +0800 Subject: [PATCH] rename cache function from func() (interface{}, error) to func(ctx context.Context) (value interface{}, err error) for package gcache; add cache for function Tables of gdb.Core; improve Where condition with prefix handling for package gdb --- database/gdb/gdb_core.go | 24 ++++++++++++------ database/gdb/gdb_driver_mysql.go | 2 +- database/gdb/gdb_driver_oracle.go | 4 +-- database/gdb/gdb_func.go | 21 +++++++++++++--- database/gdb/gdb_model_select.go | 11 +++++--- net/ghttp/ghttp_server_router_serve.go | 6 +++-- os/gcache/gcache.go | 15 ++++++----- os/gcache/gcache_adapter.go | 8 +++--- os/gcache/gcache_adapter_memory.go | 28 ++++++++++----------- os/gcache/gcache_adapter_memory_data.go | 9 ++++--- os/gcache/gcache_adapter_redis.go | 18 ++++++------- os/gcache/gcache_cache_must.go | 4 +-- os/gcache/gcache_z_example_cache_test.go | 17 +++++++------ os/gcache/gcache_z_unit_test.go | 32 ++++++++++++------------ os/gfile/gfile_cache.go | 2 +- 15 files changed, 118 insertions(+), 83 deletions(-) diff --git a/database/gdb/gdb_core.go b/database/gdb/gdb_core.go index c4c495f00..34befb5db 100644 --- a/database/gdb/gdb_core.go +++ b/database/gdb/gdb_core.go @@ -652,16 +652,26 @@ func (c *Core) writeSqlToLogger(ctx context.Context, sql *Sql) { // HasTable determine whether the table name exists in the database. func (c *Core) HasTable(name string) (bool, error) { - tableList, err := c.db.Tables(c.GetCtx()) + result, err := c.GetCache().GetOrSetFunc( + c.GetCtx(), + fmt.Sprintf(`HasTable: %s`, name), + func(ctx context.Context) (interface{}, error) { + tableList, err := c.db.Tables(ctx) + if err != nil { + return false, err + } + for _, table := range tableList { + if table == name { + return true, nil + } + } + return false, nil + }, 0, + ) if err != nil { return false, err } - for _, table := range tableList { - if table == name { - return true, nil - } - } - return false, nil + return result.Bool(), nil } // isSoftCreatedFieldName checks and returns whether given filed name is an automatic-filled created time. diff --git a/database/gdb/gdb_driver_mysql.go b/database/gdb/gdb_driver_mysql.go index 2f399882e..758f43239 100644 --- a/database/gdb/gdb_driver_mysql.go +++ b/database/gdb/gdb_driver_mysql.go @@ -106,7 +106,7 @@ func (d *DriverMysql) Tables(ctx context.Context, schema ...string) (tables []st return } -// TableFields retrieves and returns the fields information of specified table of current +// TableFields retrieves and returns the fields' information of specified table of current // schema. // // The parameter `link` is optional, if given nil it automatically retrieves a raw sql connection diff --git a/database/gdb/gdb_driver_oracle.go b/database/gdb/gdb_driver_oracle.go index 9d3de0617..872b59e8c 100644 --- a/database/gdb/gdb_driver_oracle.go +++ b/database/gdb/gdb_driver_oracle.go @@ -87,7 +87,7 @@ func (d *DriverOracle) DoCommit(ctx context.Context, link Link, sql string, args }() var index int - // Convert place holder char '?' to string ":vx". + // Convert placeholder char '?' to string ":vx". newSql, _ = gregex.ReplaceStringFunc("\\?", sql, func(s string) string { index++ return fmt.Sprintf(":v%d", index) @@ -180,7 +180,7 @@ func (d *DriverOracle) Tables(ctx context.Context, schema ...string) (tables []s return } -// TableFields retrieves and returns the fields information of specified table of current schema. +// TableFields retrieves and returns the fields' information of specified table of current schema. // // Also see DriverMysql.TableFields. func (d *DriverOracle) TableFields(ctx context.Context, table string, schema ...string) (fields map[string]*TableField, err error) { diff --git a/database/gdb/gdb_func.go b/database/gdb/gdb_func.go index 386047350..95ecd90d8 100644 --- a/database/gdb/gdb_func.go +++ b/database/gdb/gdb_func.go @@ -404,7 +404,7 @@ type formatWhereHolderInput struct { OmitNil bool OmitEmpty bool Schema string - Table string + Table string // Table is used for fields mapping and filtering internally. Prefix string // Field prefix, eg: "user.", "order.". } @@ -439,15 +439,15 @@ func formatWhereHolder(db DB, in formatWhereHolderInput) (newWhere string, newAr } case reflect.Struct: - // If the `where` parameter is defined like `xxxForDao`, it then adds `OmitNil` option for this condition, + // If the `where` parameter is DTO struct, it then adds `OmitNil` option for this condition, // which will filter all nil parameters in `where`. if isDtoStruct(in.Where) { in.OmitNil = true } - // If `where` struct implements iIterator interface, + // If `where` struct implements `iIterator` interface, // it then uses its Iterate function to iterate its key-value pairs. // For example, ListMap and TreeMap are ordered map, - // which implement iIterator interface and are index-friendly for where conditions. + // which implement `iIterator` interface and are index-friendly for where conditions. if iterator, ok := in.Where.(iIterator); ok { iterator.Iterator(func(key, value interface{}) bool { ketStr := gconv.String(key) @@ -478,6 +478,19 @@ func formatWhereHolder(db DB, in formatWhereHolderInput) (newWhere string, newAr structField reflect.StructField data = DataToMapDeep(in.Where) ) + // If `Prefix` is given, it checks and retrieves the table name. + if in.Prefix != "" { + hasTable, _ := db.GetCore().HasTable(in.Prefix) + if hasTable { + in.Table = in.Prefix + } else { + ormTagTableName := getTableNameFromOrmTag(in.Where) + if ormTagTableName != "" { + in.Table = ormTagTableName + } + } + } + // Mapping and filtering fields if `Table` is given. if in.Table != "" { data, _ = db.GetCore().mappingAndFilterData(in.Schema, in.Table, data, true) } diff --git a/database/gdb/gdb_model_select.go b/database/gdb/gdb_model_select.go index 3bd195c61..0f4d6ac91 100644 --- a/database/gdb/gdb_model_select.go +++ b/database/gdb/gdb_model_select.go @@ -600,11 +600,16 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh m.db.GetCore().guessPrimaryTableName(m.tablesInit), ) } + var ( + tableForMappingAndFiltering = m.tables + ) if len(m.whereHolder) > 0 { for _, v := range m.whereHolder { + tableForMappingAndFiltering = m.tables if v.Prefix == "" { v.Prefix = autoPrefix } + switch v.Operator { case whereHolderOperatorWhere: if conditionWhere == "" { @@ -614,7 +619,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitNil: m.option&optionOmitNilWhere > 0, OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, - Table: m.tables, + Table: tableForMappingAndFiltering, Prefix: v.Prefix, }) if len(newWhere) > 0 { @@ -632,7 +637,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitNil: m.option&optionOmitNilWhere > 0, OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, - Table: m.tables, + Table: tableForMappingAndFiltering, Prefix: v.Prefix, }) if len(newWhere) > 0 { @@ -653,7 +658,7 @@ func (m *Model) formatCondition(limit1 bool, isCountStatement bool) (conditionWh OmitNil: m.option&optionOmitNilWhere > 0, OmitEmpty: m.option&optionOmitEmptyWhere > 0, Schema: m.schema, - Table: m.tables, + Table: tableForMappingAndFiltering, Prefix: v.Prefix, }) if len(newWhere) > 0 { diff --git a/net/ghttp/ghttp_server_router_serve.go b/net/ghttp/ghttp_server_router_serve.go index 5083c2fb4..0b0f61bd9 100644 --- a/net/ghttp/ghttp_server_router_serve.go +++ b/net/ghttp/ghttp_server_router_serve.go @@ -7,6 +7,7 @@ package ghttp import ( + "context" "fmt" "strings" @@ -53,13 +54,14 @@ func (s *Server) getHandlersWithCache(r *Request) (parsedItems []*handlerParsedI value, err := s.serveCache.GetOrSetFunc( ctx, s.serveHandlerKey(method, r.URL.Path, r.GetHost()), - func() (interface{}, error) { + func(ctx context.Context) (interface{}, error) { parsedItems, hasHook, hasServe = s.searchHandlers(method, r.URL.Path, r.GetHost()) if parsedItems != nil { return &handlerCacheItem{parsedItems, hasHook, hasServe}, nil } return nil, nil - }, routeCacheDuration) + }, routeCacheDuration, + ) if err != nil { intlog.Error(ctx, err) } diff --git a/os/gcache/gcache.go b/os/gcache/gcache.go index 02b8c15f5..75016fde5 100644 --- a/os/gcache/gcache.go +++ b/os/gcache/gcache.go @@ -16,6 +16,9 @@ import ( "github.com/gogf/gf/v2/container/gvar" ) +// Func is the cache function that calculates and returns the value. +type Func func(ctx context.Context) (value interface{}, err error) + // Default cache object. var defaultCache = New() @@ -53,7 +56,7 @@ func SetIfNotExist(ctx context.Context, key interface{}, value interface{}, dura // // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil. -func SetIfNotExistFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (bool, error) { +func SetIfNotExistFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (bool, error) { return defaultCache.SetIfNotExistFunc(ctx, key, f, duration) } @@ -65,7 +68,7 @@ func SetIfNotExistFunc(ctx context.Context, key interface{}, f func() (interface // // Note that it differs from function `SetIfNotExistFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. -func SetIfNotExistFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (bool, error) { +func SetIfNotExistFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (bool, error) { return defaultCache.SetIfNotExistFuncLock(ctx, key, f, duration) } @@ -94,7 +97,7 @@ func GetOrSet(ctx context.Context, key interface{}, value interface{}, duration // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil, but it does nothing // if `value` is a function and the function result is nil. -func GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (*gvar.Var, error) { +func GetOrSetFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (*gvar.Var, error) { return defaultCache.GetOrSetFunc(ctx, key, f, duration) } @@ -108,7 +111,7 @@ func GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, e // // Note that it differs from function `GetOrSetFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. -func GetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (*gvar.Var, error) { +func GetOrSetFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (*gvar.Var, error) { return defaultCache.GetOrSetFuncLock(ctx, key, f, duration) } @@ -192,12 +195,12 @@ func MustGetOrSet(ctx context.Context, key interface{}, value interface{}, durat } // MustGetOrSetFunc acts like GetOrSetFunc, but it panics if any error occurs. -func MustGetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) *gvar.Var { +func MustGetOrSetFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) *gvar.Var { return defaultCache.MustGetOrSet(ctx, key, f, duration) } // MustGetOrSetFuncLock acts like GetOrSetFuncLock, but it panics if any error occurs. -func MustGetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) *gvar.Var { +func MustGetOrSetFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) *gvar.Var { return defaultCache.MustGetOrSetFuncLock(ctx, key, f, duration) } diff --git a/os/gcache/gcache_adapter.go b/os/gcache/gcache_adapter.go index 0921e9101..3c98011ba 100644 --- a/os/gcache/gcache_adapter.go +++ b/os/gcache/gcache_adapter.go @@ -45,7 +45,7 @@ type Adapter interface { // // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil. - SetIfNotExistFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (ok bool, err error) + SetIfNotExistFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (ok bool, err error) // SetIfNotExistFuncLock sets `key` with result of function `f` and returns true // if `key` does not exist in the cache, or else it does nothing and returns false if `key` already exists. @@ -55,7 +55,7 @@ type Adapter interface { // // Note that it differs from function `SetIfNotExistFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. - SetIfNotExistFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (ok bool, err error) + SetIfNotExistFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (ok bool, err error) // Get retrieves and returns the associated value of given `key`. // It returns nil if it does not exist, or its value is nil, or it's expired. @@ -78,7 +78,7 @@ type Adapter interface { // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil, but it does nothing // if `value` is a function and the function result is nil. - GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (result *gvar.Var, err error) + GetOrSetFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (result *gvar.Var, err error) // GetOrSetFuncLock retrieves and returns the value of `key`, or sets `key` with result of // function `f` and returns its result if `key` does not exist in the cache. The key-value @@ -90,7 +90,7 @@ type Adapter interface { // // Note that it differs from function `GetOrSetFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. - GetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (result *gvar.Var, err error) + GetOrSetFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (result *gvar.Var, err error) // Contains checks and returns true if `key` exists in the cache, or else returns false. Contains(ctx context.Context, key interface{}) (bool, error) diff --git a/os/gcache/gcache_adapter_memory.go b/os/gcache/gcache_adapter_memory.go index 539adf85c..3bb001b4b 100644 --- a/os/gcache/gcache_adapter_memory.go +++ b/os/gcache/gcache_adapter_memory.go @@ -120,7 +120,7 @@ func (c *AdapterMemory) SetIfNotExist(ctx context.Context, key interface{}, valu return false, err } if !isContained { - if _, err = c.doSetWithLockCheck(key, value, duration); err != nil { + if _, err = c.doSetWithLockCheck(ctx, key, value, duration); err != nil { return false, err } return true, nil @@ -136,17 +136,17 @@ func (c *AdapterMemory) SetIfNotExist(ctx context.Context, key interface{}, valu // // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil. -func (c *AdapterMemory) SetIfNotExistFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (bool, error) { +func (c *AdapterMemory) SetIfNotExistFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (bool, error) { isContained, err := c.Contains(ctx, key) if err != nil { return false, err } if !isContained { - value, err := f() + value, err := f(ctx) if err != nil { return false, err } - if _, err = c.doSetWithLockCheck(key, value, duration); err != nil { + if _, err = c.doSetWithLockCheck(ctx, key, value, duration); err != nil { return false, err } return true, nil @@ -162,13 +162,13 @@ func (c *AdapterMemory) SetIfNotExistFunc(ctx context.Context, key interface{}, // // Note that it differs from function `SetIfNotExistFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. -func (c *AdapterMemory) SetIfNotExistFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (bool, error) { +func (c *AdapterMemory) SetIfNotExistFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (bool, error) { isContained, err := c.Contains(ctx, key) if err != nil { return false, err } if !isContained { - if _, err = c.doSetWithLockCheck(key, f, duration); err != nil { + if _, err = c.doSetWithLockCheck(ctx, key, f, duration); err != nil { return false, err } return true, nil @@ -204,7 +204,7 @@ func (c *AdapterMemory) GetOrSet(ctx context.Context, key interface{}, value int return nil, err } if v == nil { - return c.doSetWithLockCheck(key, value, duration) + return c.doSetWithLockCheck(ctx, key, value, duration) } else { return v, nil } @@ -217,20 +217,20 @@ func (c *AdapterMemory) GetOrSet(ctx context.Context, key interface{}, value int // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil, but it does nothing // if `value` is a function and the function result is nil. -func (c *AdapterMemory) GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (*gvar.Var, error) { +func (c *AdapterMemory) GetOrSetFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (*gvar.Var, error) { v, err := c.Get(ctx, key) if err != nil { return nil, err } if v == nil { - value, err := f() + value, err := f(ctx) if err != nil { return nil, err } if value == nil { return nil, nil } - return c.doSetWithLockCheck(key, value, duration) + return c.doSetWithLockCheck(ctx, key, value, duration) } else { return v, nil } @@ -246,13 +246,13 @@ func (c *AdapterMemory) GetOrSetFunc(ctx context.Context, key interface{}, f fun // // Note that it differs from function `GetOrSetFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. -func (c *AdapterMemory) GetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (*gvar.Var, error) { +func (c *AdapterMemory) GetOrSetFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (*gvar.Var, error) { v, err := c.Get(ctx, key) if err != nil { return nil, err } if v == nil { - return c.doSetWithLockCheck(key, f, duration) + return c.doSetWithLockCheck(ctx, key, f, duration) } else { return v, nil } @@ -369,9 +369,9 @@ func (c *AdapterMemory) Close(ctx context.Context) error { // // It doubly checks the `key` whether exists in the cache using mutex writing lock // before setting it to the cache. -func (c *AdapterMemory) doSetWithLockCheck(key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) { +func (c *AdapterMemory) doSetWithLockCheck(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (result *gvar.Var, err error) { expireTimestamp := c.getInternalExpire(duration) - v, err := c.data.SetWithLock(key, value, expireTimestamp) + v, err := c.data.SetWithLock(ctx, key, value, expireTimestamp) c.eventList.PushBack(&adapterMemoryEvent{k: key, e: expireTimestamp}) return gvar.New(v), err } diff --git a/os/gcache/gcache_adapter_memory_data.go b/os/gcache/gcache_adapter_memory_data.go index 86af48724..bed8e1d4f 100644 --- a/os/gcache/gcache_adapter_memory_data.go +++ b/os/gcache/gcache_adapter_memory_data.go @@ -7,6 +7,7 @@ package gcache import ( + "context" "sync" "time" @@ -153,7 +154,7 @@ func (d *adapterMemoryData) Set(key interface{}, value adapterMemoryItem) { d.mu.Unlock() } -// Sets batch sets cache with key-value pairs by `data`, which is expired after `duration`. +// SetMap batch sets cache with key-value pairs by `data`, which is expired after `duration`. // // It does not expire if `duration` == 0. // It deletes the keys of `data` if `duration` < 0 or given `value` is nil. @@ -169,14 +170,14 @@ func (d *adapterMemoryData) SetMap(data map[interface{}]interface{}, expireTime return nil } -func (d *adapterMemoryData) SetWithLock(key interface{}, value interface{}, expireTimestamp int64) (interface{}, error) { +func (d *adapterMemoryData) SetWithLock(ctx context.Context, key interface{}, value interface{}, expireTimestamp int64) (interface{}, error) { d.mu.Lock() defer d.mu.Unlock() if v, ok := d.data[key]; ok && !v.IsExpired() { return v.v, nil } - if f, ok := value.(func() (interface{}, error)); ok { - v, err := f() + if f, ok := value.(Func); ok { + v, err := f(ctx) if err != nil { return nil, err } diff --git a/os/gcache/gcache_adapter_redis.go b/os/gcache/gcache_adapter_redis.go index 03a0e5d27..7dec1f2d4 100644 --- a/os/gcache/gcache_adapter_redis.go +++ b/os/gcache/gcache_adapter_redis.go @@ -104,8 +104,8 @@ func (c *AdapterRedis) SetIfNotExist(ctx context.Context, key interface{}, value err error ) // Execute the function and retrieve the result. - if f, ok := value.(func() (interface{}, error)); ok { - value, err = f() + if f, ok := value.(Func); ok { + value, err = f(ctx) if value == nil { return false, err } @@ -143,8 +143,8 @@ func (c *AdapterRedis) SetIfNotExist(ctx context.Context, key interface{}, value // // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil. -func (c *AdapterRedis) SetIfNotExistFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (ok bool, err error) { - value, err := f() +func (c *AdapterRedis) SetIfNotExistFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (ok bool, err error) { + value, err := f(ctx) if err != nil { return false, err } @@ -159,8 +159,8 @@ func (c *AdapterRedis) SetIfNotExistFunc(ctx context.Context, key interface{}, f // // Note that it differs from function `SetIfNotExistFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. -func (c *AdapterRedis) SetIfNotExistFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (ok bool, err error) { - value, err := f() +func (c *AdapterRedis) SetIfNotExistFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (ok bool, err error) { + value, err := f(ctx) if err != nil { return false, err } @@ -198,13 +198,13 @@ func (c *AdapterRedis) GetOrSet(ctx context.Context, key interface{}, value inte // It does not expire if `duration` == 0. // It deletes the `key` if `duration` < 0 or given `value` is nil, but it does nothing // if `value` is a function and the function result is nil. -func (c *AdapterRedis) GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (result *gvar.Var, err error) { +func (c *AdapterRedis) GetOrSetFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) (result *gvar.Var, err error) { v, err := c.Get(ctx, key) if err != nil { return nil, err } if v == nil { - value, err := f() + value, err := f(ctx) if err != nil { return nil, err } @@ -227,7 +227,7 @@ func (c *AdapterRedis) GetOrSetFunc(ctx context.Context, key interface{}, f func // // Note that it differs from function `GetOrSetFunc` is that the function `f` is executed within // writing mutex lock for concurrent safety purpose. -func (c *AdapterRedis) GetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (result *gvar.Var, err error) { +func (c *AdapterRedis) GetOrSetFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) (result *gvar.Var, err error) { return c.GetOrSetFunc(ctx, key, f, duration) } diff --git a/os/gcache/gcache_cache_must.go b/os/gcache/gcache_cache_must.go index ddb7946df..65961a001 100644 --- a/os/gcache/gcache_cache_must.go +++ b/os/gcache/gcache_cache_must.go @@ -32,7 +32,7 @@ func (c *Cache) MustGetOrSet(ctx context.Context, key interface{}, value interfa } // MustGetOrSetFunc acts like GetOrSetFunc, but it panics if any error occurs. -func (c *Cache) MustGetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) *gvar.Var { +func (c *Cache) MustGetOrSetFunc(ctx context.Context, key interface{}, f Func, duration time.Duration) *gvar.Var { v, err := c.GetOrSetFunc(ctx, key, f, duration) if err != nil { panic(err) @@ -41,7 +41,7 @@ func (c *Cache) MustGetOrSetFunc(ctx context.Context, key interface{}, f func() } // MustGetOrSetFuncLock acts like GetOrSetFuncLock, but it panics if any error occurs. -func (c *Cache) MustGetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) *gvar.Var { +func (c *Cache) MustGetOrSetFuncLock(ctx context.Context, key interface{}, f Func, duration time.Duration) *gvar.Var { v, err := c.GetOrSetFuncLock(ctx, key, f, duration) if err != nil { panic(err) diff --git a/os/gcache/gcache_z_example_cache_test.go b/os/gcache/gcache_z_example_cache_test.go index 96b96e3f3..328eae95f 100644 --- a/os/gcache/gcache_z_example_cache_test.go +++ b/os/gcache/gcache_z_example_cache_test.go @@ -1,6 +1,7 @@ package gcache_test import ( + "context" "fmt" "time" @@ -360,14 +361,14 @@ func ExampleCache_GetOrSetFunc() { // GetOrSetFunc retrieves and returns the value of `key`, or sets `key` with result of function `f` // and returns its result if `key` does not exist in the cache. - c.GetOrSetFunc(ctx, "k1", func() (interface{}, error) { + c.GetOrSetFunc(ctx, "k1", func(ctx context.Context) (value interface{}, err error) { return "v1", nil }, 10000*time.Millisecond) v, _ := c.Get(ctx, "k1") fmt.Println(v) // If func returns nil, no action is taken - c.GetOrSetFunc(ctx, "k2", func() (interface{}, error) { + c.GetOrSetFunc(ctx, "k2", func(ctx context.Context) (value interface{}, err error) { return nil, nil }, 10000*time.Millisecond) v1, _ := c.Get(ctx, "k2") @@ -384,14 +385,14 @@ func ExampleCache_GetOrSetFuncLock() { c := gcache.New() // Modify locking Note that the function `f` should be executed within writing mutex lock for concurrent safety purpose. - c.GetOrSetFuncLock(ctx, "k1", func() (interface{}, error) { + c.GetOrSetFuncLock(ctx, "k1", func(ctx context.Context) (value interface{}, err error) { return "v1", nil }, 0) v, _ := c.Get(ctx, "k1") fmt.Println(v) // Modification failed - c.GetOrSetFuncLock(ctx, "k1", func() (interface{}, error) { + c.GetOrSetFuncLock(ctx, "k1", func(ctx context.Context) (value interface{}, err error) { return "update v1", nil }, 0) v, _ = c.Get(ctx, "k1") @@ -528,13 +529,13 @@ func ExampleCache_MustGetOrSetFunc() { c := gcache.New() // MustGetOrSetFunc acts like GetOrSetFunc, but it panics if any error occurs. - c.MustGetOrSetFunc(ctx, "k1", func() (interface{}, error) { + c.MustGetOrSetFunc(ctx, "k1", func(ctx context.Context) (value interface{}, err error) { return "v1", nil }, 10000*time.Millisecond) v := c.MustGet(ctx, "k1") fmt.Println(v) - c.MustGetOrSetFunc(ctx, "k2", func() (interface{}, error) { + c.MustGetOrSetFunc(ctx, "k2", func(ctx context.Context) (value interface{}, err error) { return nil, nil }, 10000*time.Millisecond) v1 := c.MustGet(ctx, "k2") @@ -552,14 +553,14 @@ func ExampleCache_MustGetOrSetFuncLock() { c := gcache.New() // MustGetOrSetFuncLock acts like GetOrSetFuncLock, but it panics if any error occurs. - c.MustGetOrSetFuncLock(ctx, "k1", func() (interface{}, error) { + c.MustGetOrSetFuncLock(ctx, "k1", func(ctx context.Context) (value interface{}, err error) { return "v1", nil }, 0) v := c.MustGet(ctx, "k1") fmt.Println(v) // Modification failed - c.MustGetOrSetFuncLock(ctx, "k1", func() (interface{}, error) { + c.MustGetOrSetFuncLock(ctx, "k1", func(ctx context.Context) (value interface{}, err error) { return "update v1", nil }, 0) v = c.MustGet(ctx, "k1") diff --git a/os/gcache/gcache_z_unit_test.go b/os/gcache/gcache_z_unit_test.go index 1f10b4223..73117834c 100644 --- a/os/gcache/gcache_z_unit_test.go +++ b/os/gcache/gcache_z_unit_test.go @@ -238,7 +238,7 @@ func TestCache_SetIfNotExist(t *testing.T) { func TestCache_SetIfNotExistFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - exist, err := cache.SetIfNotExistFunc(ctx, 1, func() (interface{}, error) { + exist, err := cache.SetIfNotExistFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) t.AssertNil(err) @@ -247,7 +247,7 @@ func TestCache_SetIfNotExistFunc(t *testing.T) { v, _ := cache.Get(ctx, 1) t.Assert(v, 11) - exist, err = cache.SetIfNotExistFunc(ctx, 1, func() (interface{}, error) { + exist, err = cache.SetIfNotExistFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 22, nil }, 0) t.AssertNil(err) @@ -259,7 +259,7 @@ func TestCache_SetIfNotExistFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { gcache.Remove(ctx, g.Slice{1, 2, 3}...) - ok, err := gcache.SetIfNotExistFunc(ctx, 1, func() (interface{}, error) { + ok, err := gcache.SetIfNotExistFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) t.AssertNil(err) @@ -268,7 +268,7 @@ func TestCache_SetIfNotExistFunc(t *testing.T) { v, _ := gcache.Get(ctx, 1) t.Assert(v, 11) - ok, err = gcache.SetIfNotExistFunc(ctx, 1, func() (interface{}, error) { + ok, err = gcache.SetIfNotExistFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 22, nil }, 0) t.AssertNil(err) @@ -282,7 +282,7 @@ func TestCache_SetIfNotExistFunc(t *testing.T) { func TestCache_SetIfNotExistFuncLock(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - exist, err := cache.SetIfNotExistFuncLock(ctx, 1, func() (interface{}, error) { + exist, err := cache.SetIfNotExistFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) t.AssertNil(err) @@ -291,7 +291,7 @@ func TestCache_SetIfNotExistFuncLock(t *testing.T) { v, _ := cache.Get(ctx, 1) t.Assert(v, 11) - exist, err = cache.SetIfNotExistFuncLock(ctx, 1, func() (interface{}, error) { + exist, err = cache.SetIfNotExistFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 22, nil }, 0) t.AssertNil(err) @@ -303,7 +303,7 @@ func TestCache_SetIfNotExistFuncLock(t *testing.T) { gtest.C(t, func(t *gtest.T) { gcache.Remove(ctx, g.Slice{1, 2, 3}...) - exist, err := gcache.SetIfNotExistFuncLock(ctx, 1, func() (interface{}, error) { + exist, err := gcache.SetIfNotExistFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) t.AssertNil(err) @@ -312,7 +312,7 @@ func TestCache_SetIfNotExistFuncLock(t *testing.T) { v, _ := gcache.Get(ctx, 1) t.Assert(v, 11) - exist, err = gcache.SetIfNotExistFuncLock(ctx, 1, func() (interface{}, error) { + exist, err = gcache.SetIfNotExistFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 22, nil }, 0) t.AssertNil(err) @@ -377,13 +377,13 @@ func TestCache_GetOrSet(t *testing.T) { func TestCache_GetOrSetFunc(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - cache.GetOrSetFunc(ctx, 1, func() (interface{}, error) { + cache.GetOrSetFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) v, _ := cache.Get(ctx, 1) t.Assert(v, 11) - cache.GetOrSetFunc(ctx, 1, func() (interface{}, error) { + cache.GetOrSetFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 111, nil }, 0) v, _ = cache.Get(ctx, 1) @@ -391,13 +391,13 @@ func TestCache_GetOrSetFunc(t *testing.T) { gcache.Remove(ctx, g.Slice{1, 2, 3}...) - gcache.GetOrSetFunc(ctx, 1, func() (interface{}, error) { + gcache.GetOrSetFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) v, _ = cache.Get(ctx, 1) t.Assert(v, 11) - gcache.GetOrSetFunc(ctx, 1, func() (interface{}, error) { + gcache.GetOrSetFunc(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 111, nil }, 0) v, _ = cache.Get(ctx, 1) @@ -408,26 +408,26 @@ func TestCache_GetOrSetFunc(t *testing.T) { func TestCache_GetOrSetFuncLock(t *testing.T) { gtest.C(t, func(t *gtest.T) { cache := gcache.New() - cache.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) { + cache.GetOrSetFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) v, _ := cache.Get(ctx, 1) t.Assert(v, 11) - cache.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) { + cache.GetOrSetFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 111, nil }, 0) v, _ = cache.Get(ctx, 1) t.Assert(v, 11) gcache.Remove(ctx, g.Slice{1, 2, 3}...) - gcache.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) { + gcache.GetOrSetFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 11, nil }, 0) v, _ = cache.Get(ctx, 1) t.Assert(v, 11) - gcache.GetOrSetFuncLock(ctx, 1, func() (interface{}, error) { + gcache.GetOrSetFuncLock(ctx, 1, func(ctx context.Context) (value interface{}, err error) { return 111, nil }, 0) v, _ = cache.Get(ctx, 1) diff --git a/os/gfile/gfile_cache.go b/os/gfile/gfile_cache.go index a2190fcb8..f24e92c11 100644 --- a/os/gfile/gfile_cache.go +++ b/os/gfile/gfile_cache.go @@ -57,7 +57,7 @@ func GetBytesWithCache(path string, duration ...time.Duration) []byte { if len(duration) > 0 { expire = duration[0] } - r, _ := internalCache.GetOrSetFuncLock(ctx, cacheKey, func() (interface{}, error) { + r, _ := internalCache.GetOrSetFuncLock(ctx, cacheKey, func(ctx context.Context) (interface{}, error) { b := GetBytes(path) if b != nil { // Adding this `path` to gfsnotify,