jackc / pgx

PostgreSQL driver and toolkit for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

check ForEachRow second argument includes all field in row

dmitryuck opened this issue · comments

Is your feature request related to a problem? Please describe.
a suggestion to make pgx.ForEachRow check if the second parameter []any{...} contains all the fields in the row, because if one missing method returns zero rows

Describe the solution you'd like
pgx.ForEachRow(rows, []any{&id, &parentId, &imageUrl, &title, &descr, &languages}, func() error {...})

here I need to be sure I do a scan for all fields, checking statically by compiler, or return an error message which fields are missing

Describe alternatives you've considered
of adding a generic to the function to compare what row structure I use and fields want to receive

type MyStruct struct {
  id int
  name string
}

var (
  id int
  name string
)

pgx.ForEachRow[MyStruct](rows, []any{&id, &name}, func() error {...})

or

type MyStruct struct {
  id int
  name string
}

var myStruct MyStruct

pgx.ForEachRow[MyStruct](rows, &myStruct, func() error {...})

I don't understand. pgx.ForEachRow already returns an error if the number of arguments does not match the number of fields in the row. You'll get an error like number of field descriptions must equal number of destinations, got 2 and 1.

var (
		id        uint8
		parentId  pgtype.Int8
		imageUrl  pgtype.Text
		title     string
		descr     pgtype.Text
		languages []string
	)

	var categoryDto []dto.CategoryDto

	pgx.ForEachRow(rows, []any{/*&id, &parentId, &imageUrl, &title, &descr, &languages*/}, func() error {
		crdto := dto.CategoryDto{
			Id:        id,
			ParentId:  uint8(parentId.Int64),
			ImageUrl:  string(imageUrl.String),
			Title:     title,
			Descr:     string(descr.String),
			Languages: languages,
		}

		categoryDto = append(categoryDto, crdto)

		return nil
	})

	fmt.Printf("resp dto: %+v \n", categoryDto) // resp dto: []

Here is my piece of code, as you see I commented out all the fields in a function call and it compiles success, but return me an empty slice, no errors, no warnings

It would appear you are not checking the error from pgx.ForEachRow.

See my example:

package main

import (
	"context"
	"log"
	"os"

	"github.com/jackc/pgx/v5"
)

func main() {
	ctx := context.Background()

	conn, err := pgx.Connect(ctx, os.Getenv("DATABASE_URL"))
	if err != nil {
		log.Fatal(err)
	}
	defer conn.Close(ctx)

	var a, b, c int32

	rows, err := conn.Query(ctx, "select 1 * n, 2 * n, 3 * n from generate_series(1, 5) n")
	if err != nil {
		log.Fatal(err)
	}

	_, err = pgx.ForEachRow(rows, []any{ /*&a, &b, &c*/ }, func() error {
		log.Println(a, b, c)
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
}

Results:

2023/12/25 09:39:35 number of field descriptions must equal number of destinations, got 3 and 0
exit status 1