jmoiron / sqlx

general purpose extensions to golang's database/sql
http://jmoiron.github.io/sqlx/
MIT License
15.92k stars 1.07k forks source link

sqlx.select method when specifying an interface slice as desination #839

Open alexanderruch opened 1 year ago

alexanderruch commented 1 year ago

Hi, If you specify an interface array as the destination in the sqlx.select method, the following error is returned: must pass a pointer, not a value, to StructScan destination.

var clients []domain.IClient sqlx.Select(clients, SELECT * FROM clients WHERE user_id=$1, "1")

When calling the sqlx.Get method with a single interface, everything works as expected.

// domain.NewClient() // func NewClient() IClient { // return &client{} // } client := domain.NewClient() sqlx.Get(client, SELECT * FROM users WHERE id=$1, id)

Is there a solution for this?

p.s. The struct should not be used without an interface in this project, because certain setters exist here and only values should be set this way.

type IClient interface { GetId() string GetKeyHash () string SetKeyHash (identity string) }

type client struct { Id string json:"id" db:"id" KeyHash string json:"public_key_hash"db:"public_key_hash" }

func NewClient() IClient { return &client{} }

Best Regards Alex

silbinarywolf commented 1 year ago

Looks like this currently isn't possible with sqlx, even when you pass in a pointer to a slice to select, you get the following error:

non-struct dest type interface with >1 columns (4)

The problem with what you're trying to achieve here is that there is currently no way for SQLX to know what implementation to use when you pass clients to the Select function.

But as an aside, when using Select you need to change the pattern from this:

var clients []domain.IClient
sqlx.Select(clients, SELECT * FROM clients WHERE user_id=$1, "1")

...to this (ie. &clients)

var clients []domain.IClient
sqlx.Select(&clients, SELECT * FROM clients WHERE user_id=$1, "1")