go-reform/reform

Add more helpers

AlekSi opened this issue · 7 comments

  • 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

*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?

That was a bug. 🐞 Updated description.

Hello. Does anyone work on this?

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

I'll take this!

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.