func getFieldInfo(typ reflect.Type) fieldInfo {
	finfoLock.RLock()
	finfo, ok := finfos[typ]
	finfoLock.RUnlock()
	if ok {
		return finfo
	}
	finfo = make(fieldInfo)
	n := typ.NumField()
	for i := 0; i < n; i++ {
		f := typ.Field(i)
		tag := f.Tag.Get(TagName)
		if f.PkgPath != "" || tag == "-" {
			continue
		}
		if f.Anonymous && f.Type.Kind() == reflect.Struct {
			for k, v := range getFieldInfo(f.Type) {
				finfo[k] = append([]int{i}, v...)
			}
			continue
		}
		if tag == "" {
			tag = f.Name
		}
		tag = NameMapper(tag)
		finfo[tag] = []int{i}
	}
	finfoLock.Lock()
	finfos[typ] = finfo
	finfoLock.Unlock()
	return finfo
}
getFieldInfo creates a fieldInfo for the provided type. Fields that are not tagged
with the "sql" tag and unexported fields are not included.
package sqlstruct
import (
	"bytes"
	"database/sql"
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
)
var NameMapper func(string) string = strings.ToLower
var finfos map[reflect.Type]fieldInfo
var finfoLock sync.RWMutex
var TagName = "sql"
type fieldInfo map[string][]int
func init() {
	finfos = make(map[reflect.Type]fieldInfo)
}
type Rows interface {
	Scan(...interface{}) error
	Columns() ([]string, error)
}