Esempio n. 1
0
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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
File: pq.go Progetto: dvarrazzo/pger
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
}