georgysavva / scany

Library for scanning data from a database into Go structs and more
MIT License
1.24k stars 67 forks source link

fields: add function to return expression for selecting all columns of a given struct. #48

Closed henvic closed 1 year ago

henvic commented 3 years ago

Hi,

I'm sending this for the sake of giving back upstream, feel free to use it as you wish.

We've created a function to help us use scany more productively on some experiments we're running with regards to:

By the way,

Thanks.

georgysavva commented 3 years ago

Hello! This feature might be a good improvement to scany capabilities actually.
I need to think of a proper place where to put these new functions to keep the API consistent. Your feature might be also related in terms of API to another functional that I would like to implement, see this thread: https://github.com/georgysavva/scany/issues/12#issuecomment-679303703.

BTW, The first thing that comes to my mind about your current implementation is how Wildcard() function should handle nested structs? Consider the following example:

type Place struct {
    Name string
   Address string
}

type User struct {
    Place *Place 
}

If we call .Fields() function on the User type it returns: []string{"place.name", "place.address"} which is expected. Then we call .Wildcard() it will return: place.name, place.address and I see a problem here because in most databases it means that the result column name in the SELECT statement will be "name" and "address" and you need an explicit name alias: place.name AS "place.name", place.address AS "place.address". Otherwise, you won't be able to scany into User type with scany capabilities and I believe this is something you want to achieve!

The caching is good, but it should be rather inside the GetColumnToFieldIndexMap() function. This is something I would also like to add in the future, see: https://github.com/georgysavva/scany/issues/25#issuecomment-756498314

henvic commented 3 years ago

Hi Georgy,

Funnily enough, today we identified more problems with handling nested structures (panic, and part of what you said). I'm fixing it on my end and will get back once I've it working properly.

Also, sometimes you have a JSON or JSONB data type on your table and this would generate a list of each individual field mapped, so maybe an option called json akin to encoding/json's omitempty tag option is necessary to make this work as intended.

Possible usage:

type Table struct {
    Column      Nested `db:"column,json"`
}

or

type Table struct {
    Column      Nested `db:",json"`
}

/cc @Dalot (kudos for identifying the issues).

henvic commented 3 years ago

Hi @georgysavva,

I've done the improvements discussed above, and separated a global cache layer prototype in a second commit.

georgysavva commented 1 year ago

Hi @henvic. Thank you so much for working on this feature. It took me a while to get back to you. Unfortunately, I've decided not to include that feature in scany since there are some design complications I am wary of.

Again, deeply sorry for not accepting your work.

henvic commented 1 year ago

Hey Georgy, no worries! Thank you for scany, regardless!