Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more helpers #144

Open
AlekSi opened this issue Jan 3, 2018 · 7 comments
Open

Add more helpers #144

AlekSi opened this issue Jan 3, 2018 · 7 comments

Comments

@AlekSi
Copy link
Member

AlekSi commented Jan 3, 2018

  • Functions to convert Struct from/to map[string]interface{} by field or column names.
func StructFields(s Struct) map[string]interface{} { … }
func StructColumns(s Struct) map[string]interface{} { … }
func MapFields(fields map[string]interface{}, s Struct) { … }
func MapColumns(columns map[string]interface{}, s Struct) { … }
  • Method to scan *sql.Row into the Struct by column names.
func (q *Querier) NextRowColumns(str Struct, rows *sql.Rows) error
@AlekSi AlekSi added the feature label Jan 3, 2018
@AlekSi AlekSi added this to the v1.4.0 milestone Jan 3, 2018
@AlekSi AlekSi changed the title Add helpers for row scanning Add more helpers Jan 3, 2018
@bikbah
Copy link

bikbah commented Jan 18, 2018

*sql.Row has no Columns method, but *sql.Rows do.
https://godoc.org/database/sql#Row
https://godoc.org/database/sql#Rows.Columns

How it is proposed to scan *sql.Row by columns?

@AlekSi
Copy link
Member Author

AlekSi commented Jan 18, 2018

That was a bug. 🐞 Updated description.

@hIMEI29A
Copy link

Hello. Does anyone work on this?

@bikbah
Copy link

bikbah commented Jan 29, 2018

@hIMEI29A nope

@hIMEI29A
Copy link

i will dig.
Буду рыть )

@0xch4z
Copy link

0xch4z commented Oct 8, 2018

I'll take this!

@AlekSi AlekSi modified the milestones: v1.4.0, v1.5.0 Mar 20, 2019
@AlekSi AlekSi pinned this issue Mar 20, 2019
@Maelkum
Copy link

Maelkum commented Jul 13, 2020

Q: How would you implement this set of functions?

func MapFields(fields map[string]interface{}, s Struct) { … }
func MapColumns(columns map[string]interface{}, s Struct) { … }

My first guess for e.g. MapColumns would be iterating accross the columns of the reflect.Struct and assigning the value from the map to the corresponding pointer. E.g.

func mapColumns(m map[string]interface{}, s reform.Struct) {

	columns := s.View().Columns()
	values := s.Pointers()

	for i, column := range columns {
		// assign to values[i] the value of m[column]
	}

	// ...
}

The problem with this is that we would need to do type switches on the type of the field in the struct and handle all variants:

switch values[i].(type) {
		case *string:
			*values[i].(*string) = m[column].(string) // also make sure that the m[column] is a string too

This means having something like database/sql convertAssignRows() that handles all cases: https://github.com/golang/go/blob/go1.14.4/src/database/sql/convert.go#L219 .

OR the code could just be generated (e.g. create setters using go generate), which sounds a bit bloaty.. and perhaps a bit strange to extend the public interface for a helper function..

Sorry if it's a dumb question, I started looking into this for something I was working on, then it started looking a bit more verbose than I expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants