Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gdb: Customizing the cache in the hook, the value obtained by the Count method is incorrect #3626

Open
yimuysl001 opened this issue Jun 4, 2024 · 0 comments
Labels
bug It is confirmed a bug, but don't worry, we'll handle it.

Comments

@yimuysl001
Copy link

Go version

go1.20.14 windows/amd64

GoFrame version

2.7.1

Can this bug be reproduced with the latest release?

Option Yes

What did you do?

func main() {
	ctx := gctx.New()
	count, err := g.DB().Model("job_records").Count()
	g.Log().Debug(ctx, count, err)
	count, err = g.DB().Model("job_records").Hook(CacheHook("", time.Minute)).Count()
	g.Log().Debug(ctx, count, err)
	count, err = g.DB().Model("job_records").Hook(CacheHook("", time.Minute)).Count()
	g.Log().Debug(ctx, count, err)

}

func CacheHook(name string, duration time.Duration, nullCache ...bool) gdb.HookHandler {
	return gdb.HookHandler{
		Select: func(ctx context.Context, in *gdb.HookSelectInput) (result gdb.Result, err error) {
			// count 条件特殊处理
			//var key = ""
			//if strings.Contains(in.Sql, " * ") { //  * 的语句没有 FirstResultColumn
			//	key = getCacheKey(ctx, name, in)
			//} else { // count 语句执行会出问题
			//	fromCtx := DB(name).GetCore().GetInternalCtxDataFromCtx(in.Model.GetCtx())
			//	if fromCtx != nil && fromCtx.FirstResultColumn != "" {
			//		key = getCacheKey(ctx, name, in)
			//	}
			//}
			var key = "Test" //测试用
			//if key != "" {
			get, err := g.DB(name).GetCache().Get(ctx, key)
			if err == nil && !get.IsEmpty() {
				err = get.Scan(&result)
				if err == nil {
					g.Log().Debug(ctx, "获取缓存值:", result)
					return result, nil
				}

				//}
			}

			result, err = in.Next(ctx)
			if err != nil {
				return nil, err
			}
			if result == nil || result.Len() < 1 {
				if len(nullCache) > 0 && nullCache[0] {
					result = make(gdb.Result, 0)
				} else {
					return
				}

			}
			//if key != "" {
			g.Log().Debug(ctx, "添加缓存:", result)
			_ = g.DB(name).GetCache().Set(ctx, key, result, duration)
			//}

			return
		},
	}
}

// 执行结果 
// 5
//添加缓存: [{"COUNT(1)":5}]
//5
//获取缓存值: [{"COUNT(1)":5}]
//0

What did you see happen?

gdb自带的缓存,再新增和修改后,无法及时的对缓存进行刷新,所以再提供的hook方法中自己添加了个缓存方法。但是运行过程中发现,使用count方法无法正常返回应有的值。
跟踪代码发现,count方法在hook之后会有特殊处理

var (
		sqlWithHolder, holderArgs = m.getFormattedSqlAndArgs(ctx, queryTypeCount, false)
		all, err                  = m.doGetAllBySql(ctx, queryTypeCount, sqlWithHolder, holderArgs...)
	)
	if err != nil {
		return 0, err
	}
	if len(all) > 0 {
		if internalData := core.getInternalColumnFromCtx(ctx); internalData != nil {
			if v, ok := all[0][internalData.FirstResultColumn]; ok {
				return v.Int(), nil
			}
		} else {
			return 0, gerror.NewCode(
				gcode.CodeInternalError,
				`query count error: the internal context data is missing. there's internal issue should be fixed`,
			)
		}
	}

导致返回缓存的值和count实际使用的不一样

What did you expect to see?

希望hook返回的是特殊修改后的值或者将 queryTypeValue, queryTypeCount 在hook中能获取到。

@yimuysl001 yimuysl001 added the bug It is confirmed a bug, but don't worry, we'll handle it. label Jun 4, 2024
@Issues-translate-bot Issues-translate-bot changed the title gdb: 在hook当中自定义缓存, Count方法获取值不正确 gdb: Customizing the cache in the hook, the value obtained by the Count method is incorrect Jun 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it.
Projects
None yet
Development

No branches or pull requests

1 participant