func (r *libpqRows) Next(dest []driver.Value) error { if r.currRow >= r.nrows { return io.EOF } currRow := C.int(r.currRow) r.currRow++ for i := 0; i < len(dest); i++ { ci := C.int(i) // check for NULL if int(C.PQgetisnull(r.res, currRow, ci)) == 1 { dest[i] = nil continue } var err error val := C.GoString(C.PQgetvalue(r.res, currRow, ci)) switch vtype := int(C.PQftype(r.res, ci)); vtype { case r.s.c.oids.Bytea: if !strings.HasPrefix(val, `\x`) { return errors.New("libpq: invalid byte string format") } dest[i], err = hex.DecodeString(val[2:]) if err != nil { return errors.New(fmt.Sprint("libpq: could not decode hex string: %s", err)) } case r.s.c.oids.Date: dest[i], err = time.Parse("2006-01-02", val) if err != nil { return errors.New(fmt.Sprint("libpq: could not parse DATE %s: %s", val, err)) } case r.s.c.oids.Timestamp: dest[i], err = time.Parse("2006-01-02 15:04:05", val) if err != nil { return errors.New(fmt.Sprint("libpq: could not parse TIMESTAMP %s: %s", val, err)) } case r.s.c.oids.TimestampTz: dest[i], err = time.Parse(timeFormat, val) if err != nil { return errors.New(fmt.Sprint("libpq: could not parse TIMESTAMP WITH TIME ZONE %s: %s", val, err)) } case r.s.c.oids.Time: dest[i], err = time.Parse("15:04:05", val) if err != nil { return errors.New(fmt.Sprint("libpq: could not parse TIME %s: %s", val, err)) } case r.s.c.oids.TimeTz: dest[i], err = time.Parse("15:04:05-07", val) if err != nil { return errors.New(fmt.Sprint("libpq: could not parse TIME WITH TIME ZONE %s: %s", val, err)) } default: dest[i] = val } } return nil }
func (r *driverRows) Next(dest []driver.Value) error { r.currRow++ if r.currRow >= r.nrows { return io.EOF } for i := 0; i < len(dest); i++ { if int(C.PQgetisnull(r.res, C.int(r.currRow), C.int(i))) == 1 { dest[i] = nil continue } val := C.GoString(C.PQgetvalue(r.res, C.int(r.currRow), C.int(i))) switch vtype := uint(C.PQftype(r.res, C.int(i))); vtype { case BOOLOID: if val == "t" { dest[i] = "true" } else { dest[i] = "false" } case BYTEAOID: if !strings.HasPrefix(val, "\\x") { return argErr(i, "[]byte", "invalid byte string format") } buf, err := hex.DecodeString(val[2:]) if err != nil { return argErr(i, "[]byte", err.Error()) } dest[i] = buf case CHAROID, BPCHAROID, VARCHAROID, TEXTOID, INT2OID, INT4OID, INT8OID, OIDOID, XIDOID, FLOAT8OID, FLOAT4OID, DATEOID, TIMEOID, TIMESTAMPOID, TIMESTAMPTZOID, INTERVALOID, TIMETZOID, NUMERICOID: dest[i] = val default: return errors.New(fmt.Sprintf("unsupported type oid: %d", vtype)) } } return nil }
func next(r *PgRows, dest []driver.Value) error { if r.cur >= int(C.PQntuples(r.result)) { return io.EOF } // TODO: cache oids // TODO: extendibility for i := 0; i < len(dest); i++ { if 0 == int(C.PQgetisnull(r.result, C.int(r.cur), C.int(i))) { oid := int(C.PQftype(r.result, C.int(i))) data := C.PQgetvalue(r.result, C.int(r.cur), C.int(i)) length := C.PQgetlength(r.result, C.int(r.cur), C.int(i)) var err error dest[i], err = typecast(oid, data, length, r) if err != nil { return err } } else { dest[i] = nil } } r.cur++ return nil }