Beispiel #1
0
func newResult(res *C.PGresult) *driverRows {
	ncols := int(C.PQnfields(res))
	nrows := int(C.PQntuples(res))
	result := &driverRows{res: res, nrows: nrows, currRow: -1, ncols: ncols, cols: nil}
	runtime.SetFinalizer(result, (*driverRows).Close)
	return result
}
Beispiel #2
0
func newResult(res *C.PGresult) *Result {
	ncols := int(C.PQnfields(res))
	nrows := int(C.PQntuples(res))
	result := &Result{res: res, nrows: nrows, currRow: -1, ncols: ncols, cols: nil}
	runtime.SetFinalizer(result, (*Result).Clear)
	return result
}
Beispiel #3
0
func (s *libpqStmt) Query(args []driver.Value) (driver.Rows, error) {
	// execute prepared statement
	cres, err := s.exec(args)
	if err != nil {
		return nil, err
	}

	// check to see if this was a "LISTEN"
	if C.GoString(C.PQcmdStatus(cres)) == "LISTEN" {
		C.PQclear(cres)
		return &libpqListenRows{s.c}, nil
	}

	return &libpqRows{
		s:       s,
		res:     cres,
		ncols:   int(C.PQnfields(cres)),
		nrows:   int(C.PQntuples(cres)),
		currRow: 0,
		cols:    nil,
	}, nil
}
Beispiel #4
0
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
}