func ctxDriverExec(ctx context.Context, execer driver.Execer, query string, nvdargs []driver.NamedValue) (driver.Result, error) { if execerCtx, is := execer.(driver.ExecerContext); is { return execerCtx.ExecContext(ctx, query, nvdargs) } dargs, err := namedValueToValue(nvdargs) if err != nil { return nil, err } if ctx.Done() == context.Background().Done() { return execer.Exec(query, dargs) } type R struct { err error panic interface{} resi driver.Result } rc := make(chan R, 1) go func() { r := R{} defer func() { if v := recover(); v != nil { r.panic = v } rc <- r }() r.resi, r.err = execer.Exec(query, dargs) }() select { case <-ctx.Done(): go func() { <-rc close(rc) }() return nil, ctx.Err() case r := <-rc: if r.panic != nil { panic(r.panic) } return r.resi, r.err } }
func ctxDriverExec(ctx context.Context, execer driver.Execer, query string, nvdargs []driver.NamedValue) (driver.Result, error) { if execerCtx, is := execer.(driver.ExecerContext); is { return execerCtx.ExecContext(ctx, query, nvdargs) } dargs, err := namedValueToValue(nvdargs) if err != nil { return nil, err } resi, err := execer.Exec(query, dargs) if err == nil { select { default: case <-ctx.Done(): return resi, ctx.Err() } } return resi, err }