func ctxDriverStmtExec(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Result, error) { if siCtx, is := si.(driver.StmtExecContext); is { return siCtx.ExecContext(ctx, nvdargs) } dargs, err := namedValueToValue(nvdargs) if err != nil { return nil, err } resi, err := si.Exec(dargs) if err == nil { select { default: case <-ctx.Done(): return resi, ctx.Err() } } return resi, err }
func ctxDriverStmtExec(ctx context.Context, si driver.Stmt, nvdargs []driver.NamedValue) (driver.Result, error) { if siCtx, is := si.(driver.StmtExecContext); is { return siCtx.ExecContext(ctx, nvdargs) } dargs, err := namedValueToValue(nvdargs) if err != nil { return nil, err } if ctx.Done() == context.Background().Done() { return si.Exec(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 = si.Exec(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 resultFromStatement(si driver.Stmt, args ...interface{}) (Result, error) { // -1 means the driver doesn't know how to count the number of // placeholders, so we won't sanity check input here and instead let the // driver deal with errors. if want := si.NumInput(); want != -1 && len(args) != want { return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args)) } dargs, err := driverArgs(si, args) if err != nil { return nil, err } resi, err := si.Exec(dargs) if err != nil { return nil, err } return result{resi}, nil }