func ctxDriverQuery(ctx context.Context, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) { if queryerCtx, is := queryer.(driver.QueryerContext); is { return queryerCtx.QueryContext(ctx, query, nvdargs) } dargs, err := namedValueToValue(nvdargs) if err != nil { return nil, err } if ctx.Done() == context.Background().Done() { return queryer.Query(query, dargs) } type R struct { err error panic interface{} rowsi driver.Rows } rc := make(chan R, 1) go func() { r := R{} defer func() { if v := recover(); v != nil { r.panic = v } rc <- r }() r.rowsi, r.err = queryer.Query(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.rowsi, r.err } }
func ctxDriverQuery(ctx context.Context, queryer driver.Queryer, query string, nvdargs []driver.NamedValue) (driver.Rows, error) { if queryerCtx, is := queryer.(driver.QueryerContext); is { ret, err := queryerCtx.QueryContext(ctx, query, nvdargs) return ret, err } dargs, err := namedValueToValue(nvdargs) if err != nil { return nil, err } rowsi, err := queryer.Query(query, dargs) if err == nil { select { default: case <-ctx.Done(): rowsi.Close() return nil, ctx.Err() } } return rowsi, err }
func qRows(conn driver.Queryer, query string, args ...driver.Value) (Table, error) { t := Table{} rows, err := conn.Query(query, args) if err != nil { return t, err } defer rows.Close() t.Columns = rows.Columns() buffer := make([]interface{}, len(t.Columns)) dest := make([]driver.Value, len(buffer)) for i := 0; i < len(buffer); i++ { dest[i] = &buffer[i] } cnt := 0 for { err := rows.Next(dest) if err != nil { if err != io.EOF { return t, err } break } t.Rows = append(t.Rows, make(Row, len(buffer))) for i, d := range dest { switch d := d.(type) { case []uint8: t.Rows[cnt][i] = string(d) case string: case int64: t.Rows[cnt][i] = fmt.Sprint(d) default: log.Printf("unexpected type %T", d) } } cnt++ } return t, nil }