github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/go-xorm/core/rows.go (about)

     1  package core
     2  
     3  import (
     4  	"database/sql"
     5  	"errors"
     6  	"reflect"
     7  	"sync"
     8  )
     9  
    10  type Rows struct {
    11  	*sql.Rows
    12  	Mapper IMapper
    13  }
    14  
    15  func (rs *Rows) ToMapString() ([]map[string]string, error) {
    16  	cols, err := rs.Columns()
    17  	if err != nil {
    18  		return nil, err
    19  	}
    20  
    21  	var results = make([]map[string]string, 0, 10)
    22  	for rs.Next() {
    23  		var record = make(map[string]string, len(cols))
    24  		err = rs.ScanMap(&record)
    25  		if err != nil {
    26  			return nil, err
    27  		}
    28  		results = append(results, record)
    29  	}
    30  	return results, nil
    31  }
    32  
    33  // scan data to a struct's pointer according field index
    34  func (rs *Rows) ScanStructByIndex(dest ...interface{}) error {
    35  	if len(dest) == 0 {
    36  		return errors.New("at least one struct")
    37  	}
    38  
    39  	vvvs := make([]reflect.Value, len(dest))
    40  	for i, s := range dest {
    41  		vv := reflect.ValueOf(s)
    42  		if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
    43  			return errors.New("dest should be a struct's pointer")
    44  		}
    45  
    46  		vvvs[i] = vv.Elem()
    47  	}
    48  
    49  	cols, err := rs.Columns()
    50  	if err != nil {
    51  		return err
    52  	}
    53  	newDest := make([]interface{}, len(cols))
    54  
    55  	var i = 0
    56  	for _, vvv := range vvvs {
    57  		for j := 0; j < vvv.NumField(); j++ {
    58  			newDest[i] = vvv.Field(j).Addr().Interface()
    59  			i = i + 1
    60  		}
    61  	}
    62  
    63  	return rs.Rows.Scan(newDest...)
    64  }
    65  
    66  var (
    67  	fieldCache      = make(map[reflect.Type]map[string]int)
    68  	fieldCacheMutex sync.RWMutex
    69  )
    70  
    71  func fieldByName(v reflect.Value, name string) reflect.Value {
    72  	t := v.Type()
    73  	fieldCacheMutex.RLock()
    74  	cache, ok := fieldCache[t]
    75  	fieldCacheMutex.RUnlock()
    76  	if !ok {
    77  		cache = make(map[string]int)
    78  		for i := 0; i < v.NumField(); i++ {
    79  			cache[t.Field(i).Name] = i
    80  		}
    81  		fieldCacheMutex.Lock()
    82  		fieldCache[t] = cache
    83  		fieldCacheMutex.Unlock()
    84  	}
    85  
    86  	if i, ok := cache[name]; ok {
    87  		return v.Field(i)
    88  	}
    89  
    90  	return reflect.Zero(t)
    91  }
    92  
    93  // scan data to a struct's pointer according field name
    94  func (rs *Rows) ScanStructByName(dest interface{}) error {
    95  	vv := reflect.ValueOf(dest)
    96  	if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
    97  		return errors.New("dest should be a struct's pointer")
    98  	}
    99  
   100  	cols, err := rs.Columns()
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	newDest := make([]interface{}, len(cols))
   106  	var v EmptyScanner
   107  	for j, name := range cols {
   108  		f := fieldByName(vv.Elem(), rs.Mapper.Table2Obj(name))
   109  		if f.IsValid() {
   110  			newDest[j] = f.Addr().Interface()
   111  		} else {
   112  			newDest[j] = &v
   113  		}
   114  	}
   115  
   116  	return rs.Rows.Scan(newDest...)
   117  }
   118  
   119  type cacheStruct struct {
   120  	value reflect.Value
   121  	idx   int
   122  }
   123  
   124  var (
   125  	reflectCache      = make(map[reflect.Type]*cacheStruct)
   126  	reflectCacheMutex sync.RWMutex
   127  )
   128  
   129  func ReflectNew(typ reflect.Type) reflect.Value {
   130  	reflectCacheMutex.RLock()
   131  	cs, ok := reflectCache[typ]
   132  	reflectCacheMutex.RUnlock()
   133  
   134  	const newSize = 200
   135  
   136  	if !ok || cs.idx+1 > newSize-1 {
   137  		cs = &cacheStruct{reflect.MakeSlice(reflect.SliceOf(typ), newSize, newSize), 0}
   138  		reflectCacheMutex.Lock()
   139  		reflectCache[typ] = cs
   140  		reflectCacheMutex.Unlock()
   141  	} else {
   142  		reflectCacheMutex.Lock()
   143  		cs.idx = cs.idx + 1
   144  		reflectCacheMutex.Unlock()
   145  	}
   146  	return cs.value.Index(cs.idx).Addr()
   147  }
   148  
   149  // scan data to a slice's pointer, slice's length should equal to columns' number
   150  func (rs *Rows) ScanSlice(dest interface{}) error {
   151  	vv := reflect.ValueOf(dest)
   152  	if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Slice {
   153  		return errors.New("dest should be a slice's pointer")
   154  	}
   155  
   156  	vvv := vv.Elem()
   157  	cols, err := rs.Columns()
   158  	if err != nil {
   159  		return err
   160  	}
   161  
   162  	newDest := make([]interface{}, len(cols))
   163  
   164  	for j := 0; j < len(cols); j++ {
   165  		if j >= vvv.Len() {
   166  			newDest[j] = reflect.New(vvv.Type().Elem()).Interface()
   167  		} else {
   168  			newDest[j] = vvv.Index(j).Addr().Interface()
   169  		}
   170  	}
   171  
   172  	err = rs.Rows.Scan(newDest...)
   173  	if err != nil {
   174  		return err
   175  	}
   176  
   177  	srcLen := vvv.Len()
   178  	for i := srcLen; i < len(cols); i++ {
   179  		vvv = reflect.Append(vvv, reflect.ValueOf(newDest[i]).Elem())
   180  	}
   181  	return nil
   182  }
   183  
   184  // scan data to a map's pointer
   185  func (rs *Rows) ScanMap(dest interface{}) error {
   186  	vv := reflect.ValueOf(dest)
   187  	if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
   188  		return errors.New("dest should be a map's pointer")
   189  	}
   190  
   191  	cols, err := rs.Columns()
   192  	if err != nil {
   193  		return err
   194  	}
   195  
   196  	newDest := make([]interface{}, len(cols))
   197  	vvv := vv.Elem()
   198  
   199  	for i, _ := range cols {
   200  		newDest[i] = ReflectNew(vvv.Type().Elem()).Interface()
   201  		//v := reflect.New(vvv.Type().Elem())
   202  		//newDest[i] = v.Interface()
   203  	}
   204  
   205  	err = rs.Rows.Scan(newDest...)
   206  	if err != nil {
   207  		return err
   208  	}
   209  
   210  	for i, name := range cols {
   211  		vname := reflect.ValueOf(name)
   212  		vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
   213  	}
   214  
   215  	return nil
   216  }
   217  
   218  /*func (rs *Rows) ScanMap(dest interface{}) error {
   219  	vv := reflect.ValueOf(dest)
   220  	if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
   221  		return errors.New("dest should be a map's pointer")
   222  	}
   223  
   224  	cols, err := rs.Columns()
   225  	if err != nil {
   226  		return err
   227  	}
   228  
   229  	newDest := make([]interface{}, len(cols))
   230  	err = rs.ScanSlice(newDest)
   231  	if err != nil {
   232  		return err
   233  	}
   234  
   235  	vvv := vv.Elem()
   236  
   237  	for i, name := range cols {
   238  		vname := reflect.ValueOf(name)
   239  		vvv.SetMapIndex(vname, reflect.ValueOf(newDest[i]).Elem())
   240  	}
   241  
   242  	return nil
   243  }*/
   244  type Row struct {
   245  	rows *Rows
   246  	// One of these two will be non-nil:
   247  	err error // deferred error for easy chaining
   248  }
   249  
   250  func (row *Row) Columns() ([]string, error) {
   251  	if row.err != nil {
   252  		return nil, row.err
   253  	}
   254  	return row.rows.Columns()
   255  }
   256  
   257  func (row *Row) Scan(dest ...interface{}) error {
   258  	if row.err != nil {
   259  		return row.err
   260  	}
   261  	defer row.rows.Close()
   262  
   263  	for _, dp := range dest {
   264  		if _, ok := dp.(*sql.RawBytes); ok {
   265  			return errors.New("sql: RawBytes isn't allowed on Row.Scan")
   266  		}
   267  	}
   268  
   269  	if !row.rows.Next() {
   270  		if err := row.rows.Err(); err != nil {
   271  			return err
   272  		}
   273  		return sql.ErrNoRows
   274  	}
   275  	err := row.rows.Scan(dest...)
   276  	if err != nil {
   277  		return err
   278  	}
   279  	// Make sure the query can be processed to completion with no errors.
   280  	return row.rows.Close()
   281  }
   282  
   283  func (row *Row) ScanStructByName(dest interface{}) error {
   284  	if row.err != nil {
   285  		return row.err
   286  	}
   287  	defer row.rows.Close()
   288  
   289  	if !row.rows.Next() {
   290  		if err := row.rows.Err(); err != nil {
   291  			return err
   292  		}
   293  		return sql.ErrNoRows
   294  	}
   295  	err := row.rows.ScanStructByName(dest)
   296  	if err != nil {
   297  		return err
   298  	}
   299  	// Make sure the query can be processed to completion with no errors.
   300  	return row.rows.Close()
   301  }
   302  
   303  func (row *Row) ScanStructByIndex(dest interface{}) error {
   304  	if row.err != nil {
   305  		return row.err
   306  	}
   307  	defer row.rows.Close()
   308  
   309  	if !row.rows.Next() {
   310  		if err := row.rows.Err(); err != nil {
   311  			return err
   312  		}
   313  		return sql.ErrNoRows
   314  	}
   315  	err := row.rows.ScanStructByIndex(dest)
   316  	if err != nil {
   317  		return err
   318  	}
   319  	// Make sure the query can be processed to completion with no errors.
   320  	return row.rows.Close()
   321  }
   322  
   323  // scan data to a slice's pointer, slice's length should equal to columns' number
   324  func (row *Row) ScanSlice(dest interface{}) error {
   325  	if row.err != nil {
   326  		return row.err
   327  	}
   328  	defer row.rows.Close()
   329  
   330  	if !row.rows.Next() {
   331  		if err := row.rows.Err(); err != nil {
   332  			return err
   333  		}
   334  		return sql.ErrNoRows
   335  	}
   336  	err := row.rows.ScanSlice(dest)
   337  	if err != nil {
   338  		return err
   339  	}
   340  
   341  	// Make sure the query can be processed to completion with no errors.
   342  	return row.rows.Close()
   343  }
   344  
   345  // scan data to a map's pointer
   346  func (row *Row) ScanMap(dest interface{}) error {
   347  	if row.err != nil {
   348  		return row.err
   349  	}
   350  	defer row.rows.Close()
   351  
   352  	if !row.rows.Next() {
   353  		if err := row.rows.Err(); err != nil {
   354  			return err
   355  		}
   356  		return sql.ErrNoRows
   357  	}
   358  	err := row.rows.ScanMap(dest)
   359  	if err != nil {
   360  		return err
   361  	}
   362  
   363  	// Make sure the query can be processed to completion with no errors.
   364  	return row.rows.Close()
   365  }
   366  
   367  func (row *Row) ToMapString() (map[string]string, error) {
   368  	cols, err := row.Columns()
   369  	if err != nil {
   370  		return nil, err
   371  	}
   372  
   373  	var record = make(map[string]string, len(cols))
   374  	err = row.ScanMap(&record)
   375  	if err != nil {
   376  		return nil, err
   377  	}
   378  
   379  	return record, nil
   380  }