github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/databases/orm/orm_raw.go (about)

     1  // The original package is migrated from beego and modified, you can find orignal from following link:
     2  //    "github.com/beego/beego/"
     3  //
     4  // Copyright 2023 IAC. All Rights Reserved.
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //      http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package orm
    19  
    20  import (
    21  	"database/sql"
    22  	"fmt"
    23  	"reflect"
    24  	"time"
    25  
    26  	"github.com/pkg/errors"
    27  )
    28  
    29  // raw sql string prepared statement
    30  type rawPrepare struct {
    31  	rs     *rawSet
    32  	stmt   stmtQuerier
    33  	closed bool
    34  }
    35  
    36  func (o *rawPrepare) Exec(args ...interface{}) (sql.Result, error) {
    37  	if o.closed {
    38  		return nil, ErrStmtClosed
    39  	}
    40  	flatParams := getFlatParams(nil, args, o.rs.orm.alias.TZ)
    41  	return o.stmt.Exec(flatParams...)
    42  }
    43  
    44  func (o *rawPrepare) Close() error {
    45  	o.closed = true
    46  	return o.stmt.Close()
    47  }
    48  
    49  func newRawPreparer(rs *rawSet) (RawPreparer, error) {
    50  	o := new(rawPrepare)
    51  	o.rs = rs
    52  
    53  	query := rs.query
    54  	rs.orm.alias.DbBaser.ReplaceMarks(&query)
    55  
    56  	st, err := rs.orm.db.Prepare(query)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	if Debug {
    61  		o.stmt = newStmtQueryLog(rs.orm.alias, st, query)
    62  	} else {
    63  		o.stmt = st
    64  	}
    65  	return o, nil
    66  }
    67  
    68  // raw query seter
    69  type rawSet struct {
    70  	query string
    71  	args  []interface{}
    72  	orm   *ormBase
    73  }
    74  
    75  var _ RawSeter = new(rawSet)
    76  
    77  // set args for every query
    78  func (o rawSet) SetArgs(args ...interface{}) RawSeter {
    79  	o.args = args
    80  	return &o
    81  }
    82  
    83  // execute raw sql and return sql.Result
    84  func (o *rawSet) Exec() (sql.Result, error) {
    85  	query := o.query
    86  	o.orm.alias.DbBaser.ReplaceMarks(&query)
    87  
    88  	args := getFlatParams(nil, o.args, o.orm.alias.TZ)
    89  	return o.orm.db.Exec(query, args...)
    90  }
    91  
    92  // set field value to row container
    93  func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) {
    94  	switch ind.Kind() {
    95  	case reflect.Bool:
    96  		if value == nil {
    97  			ind.SetBool(false)
    98  		} else if v, ok := value.(bool); ok {
    99  			ind.SetBool(v)
   100  		} else {
   101  			v, _ := StrTo(ToStr(value)).Bool()
   102  			ind.SetBool(v)
   103  		}
   104  
   105  	case reflect.String:
   106  		if value == nil {
   107  			ind.SetString("")
   108  		} else {
   109  			ind.SetString(ToStr(value))
   110  		}
   111  
   112  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   113  		if value == nil {
   114  			ind.SetInt(0)
   115  		} else {
   116  			val := reflect.ValueOf(value)
   117  			switch val.Kind() {
   118  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   119  				ind.SetInt(val.Int())
   120  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   121  				ind.SetInt(int64(val.Uint()))
   122  			default:
   123  				v, _ := StrTo(ToStr(value)).Int64()
   124  				ind.SetInt(v)
   125  			}
   126  		}
   127  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   128  		if value == nil {
   129  			ind.SetUint(0)
   130  		} else {
   131  			val := reflect.ValueOf(value)
   132  			switch val.Kind() {
   133  			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   134  				ind.SetUint(uint64(val.Int()))
   135  			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   136  				ind.SetUint(val.Uint())
   137  			default:
   138  				v, _ := StrTo(ToStr(value)).Uint64()
   139  				ind.SetUint(v)
   140  			}
   141  		}
   142  	case reflect.Float64, reflect.Float32:
   143  		if value == nil {
   144  			ind.SetFloat(0)
   145  		} else {
   146  			val := reflect.ValueOf(value)
   147  			switch val.Kind() {
   148  			case reflect.Float64:
   149  				ind.SetFloat(val.Float())
   150  			default:
   151  				v, _ := StrTo(ToStr(value)).Float64()
   152  				ind.SetFloat(v)
   153  			}
   154  		}
   155  
   156  	case reflect.Struct:
   157  		if value == nil {
   158  			ind.Set(reflect.Zero(ind.Type()))
   159  			return
   160  		}
   161  		switch ind.Interface().(type) {
   162  		case time.Time:
   163  			var str string
   164  			switch d := value.(type) {
   165  			case time.Time:
   166  				o.orm.alias.DbBaser.TimeFromDB(&d, o.orm.alias.TZ)
   167  				ind.Set(reflect.ValueOf(d))
   168  			case []byte:
   169  				str = string(d)
   170  			case string:
   171  				str = d
   172  			}
   173  			if str != "" {
   174  				if len(str) >= 19 {
   175  					str = str[:19]
   176  					t, err := time.ParseInLocation(formatDateTime, str, o.orm.alias.TZ)
   177  					if err == nil {
   178  						t = t.In(DefaultTimeLoc)
   179  						ind.Set(reflect.ValueOf(t))
   180  					}
   181  				} else if len(str) >= 10 {
   182  					str = str[:10]
   183  					t, err := time.ParseInLocation(formatDate, str, DefaultTimeLoc)
   184  					if err == nil {
   185  						ind.Set(reflect.ValueOf(t))
   186  					}
   187  				} else if len(str) >= 8 {
   188  					str = str[:8]
   189  					t, err := time.ParseInLocation(formatTime, str, DefaultTimeLoc)
   190  					if err == nil {
   191  						ind.Set(reflect.ValueOf(t))
   192  					}
   193  				}
   194  			}
   195  		case sql.NullString, sql.NullInt64, sql.NullFloat64, sql.NullBool:
   196  			indi := reflect.New(ind.Type()).Interface()
   197  			sc, ok := indi.(sql.Scanner)
   198  			if !ok {
   199  				return
   200  			}
   201  			err := sc.Scan(value)
   202  			if err == nil {
   203  				ind.Set(reflect.Indirect(reflect.ValueOf(sc)))
   204  			}
   205  		}
   206  
   207  	case reflect.Ptr:
   208  		if value == nil {
   209  			ind.Set(reflect.Zero(ind.Type()))
   210  			break
   211  		}
   212  		ind.Set(reflect.New(ind.Type().Elem()))
   213  		o.setFieldValue(reflect.Indirect(ind), value)
   214  	}
   215  }
   216  
   217  // set field value in loop for slice container
   218  func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) {
   219  	nInds := *nIndsPtr
   220  
   221  	cur := 0
   222  	for i := 0; i < len(sInds); i++ {
   223  		sInd := sInds[i]
   224  		eTyp := eTyps[i]
   225  
   226  		typ := eTyp
   227  		isPtr := false
   228  		if typ.Kind() == reflect.Ptr {
   229  			isPtr = true
   230  			typ = typ.Elem()
   231  		}
   232  		if typ.Kind() == reflect.Ptr {
   233  			isPtr = true
   234  			typ = typ.Elem()
   235  		}
   236  
   237  		var nInd reflect.Value
   238  		if init {
   239  			nInd = reflect.New(sInd.Type()).Elem()
   240  		} else {
   241  			nInd = nInds[i]
   242  		}
   243  
   244  		val := reflect.New(typ)
   245  		ind := val.Elem()
   246  
   247  		tpName := ind.Type().String()
   248  
   249  		if ind.Kind() == reflect.Struct {
   250  			if tpName == "time.Time" {
   251  				value := reflect.ValueOf(refs[cur]).Elem().Interface()
   252  				if isPtr && value == nil {
   253  					val = reflect.New(val.Type()).Elem()
   254  				} else {
   255  					o.setFieldValue(ind, value)
   256  				}
   257  				cur++
   258  			}
   259  		} else {
   260  			value := reflect.ValueOf(refs[cur]).Elem().Interface()
   261  			if isPtr && value == nil {
   262  				val = reflect.New(val.Type()).Elem()
   263  			} else {
   264  				o.setFieldValue(ind, value)
   265  			}
   266  			cur++
   267  		}
   268  
   269  		if nInd.Kind() == reflect.Slice {
   270  			if isPtr {
   271  				nInd = reflect.Append(nInd, val)
   272  			} else {
   273  				nInd = reflect.Append(nInd, ind)
   274  			}
   275  		} else {
   276  			if isPtr {
   277  				nInd.Set(val)
   278  			} else {
   279  				nInd.Set(ind)
   280  			}
   281  		}
   282  
   283  		nInds[i] = nInd
   284  	}
   285  }
   286  
   287  // query data and map to container
   288  func (o *rawSet) QueryRow(containers ...interface{}) error {
   289  	var (
   290  		refs  = make([]interface{}, 0, len(containers))
   291  		sInds []reflect.Value
   292  		eTyps []reflect.Type
   293  		sMi   *modelInfo
   294  	)
   295  	structMode := false
   296  	for _, container := range containers {
   297  		val := reflect.ValueOf(container)
   298  		ind := reflect.Indirect(val)
   299  
   300  		if val.Kind() != reflect.Ptr {
   301  			panic(fmt.Errorf("<RawSeter.QueryRow> all args must be use ptr"))
   302  		}
   303  
   304  		etyp := ind.Type()
   305  		typ := etyp
   306  		if typ.Kind() == reflect.Ptr {
   307  			typ = typ.Elem()
   308  		}
   309  
   310  		sInds = append(sInds, ind)
   311  		eTyps = append(eTyps, etyp)
   312  
   313  		if typ.Kind() == reflect.Struct && typ.String() != "time.Time" {
   314  			if len(containers) > 1 {
   315  				panic(fmt.Errorf("<RawSeter.QueryRow> now support one struct only. see #384"))
   316  			}
   317  
   318  			structMode = true
   319  			fn := getFullName(typ)
   320  			if mi, ok := defaultModelCache.getByFullName(fn); ok {
   321  				sMi = mi
   322  			}
   323  		} else {
   324  			var ref interface{}
   325  			refs = append(refs, &ref)
   326  		}
   327  	}
   328  
   329  	query := o.query
   330  	o.orm.alias.DbBaser.ReplaceMarks(&query)
   331  
   332  	args := getFlatParams(nil, o.args, o.orm.alias.TZ)
   333  	rows, err := o.orm.db.Query(query, args...)
   334  	if err != nil {
   335  		if err == sql.ErrNoRows {
   336  			return ErrNoRows
   337  		}
   338  		return err
   339  	}
   340  
   341  	structTagMap := make(map[reflect.StructTag]map[string]string)
   342  
   343  	defer rows.Close()
   344  
   345  	if rows.Next() {
   346  		if structMode {
   347  			columns, err := rows.Columns()
   348  			if err != nil {
   349  				return err
   350  			}
   351  
   352  			columnsMp := make(map[string]interface{}, len(columns))
   353  
   354  			refs = make([]interface{}, 0, len(columns))
   355  			for _, col := range columns {
   356  				var ref interface{}
   357  				columnsMp[col] = &ref
   358  				refs = append(refs, &ref)
   359  			}
   360  
   361  			if err := rows.Scan(refs...); err != nil {
   362  				return err
   363  			}
   364  
   365  			ind := sInds[0]
   366  
   367  			if ind.Kind() == reflect.Ptr {
   368  				if ind.IsNil() || !ind.IsValid() {
   369  					ind.Set(reflect.New(eTyps[0].Elem()))
   370  				}
   371  				ind = ind.Elem()
   372  			}
   373  
   374  			if sMi != nil {
   375  				for _, col := range columns {
   376  					if fi := sMi.fields.GetByColumn(col); fi != nil {
   377  						value := reflect.ValueOf(columnsMp[col]).Elem().Interface()
   378  						field := ind.FieldByIndex(fi.fieldIndex)
   379  						if fi.fieldType&IsRelField > 0 {
   380  							mf := reflect.New(fi.relModelInfo.addrField.Elem().Type())
   381  							field.Set(mf)
   382  							field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
   383  						}
   384  						if fi.isFielder {
   385  							fd := field.Addr().Interface().(Fielder)
   386  							err := fd.SetRaw(value)
   387  							if err != nil {
   388  								return errors.Errorf("set raw error:%s", err)
   389  							}
   390  						} else {
   391  							o.setFieldValue(field, value)
   392  						}
   393  					}
   394  				}
   395  			} else {
   396  				// define recursive function
   397  				var recursiveSetField func(rv reflect.Value)
   398  				recursiveSetField = func(rv reflect.Value) {
   399  					for i := 0; i < rv.NumField(); i++ {
   400  						f := rv.Field(i)
   401  						fe := rv.Type().Field(i)
   402  
   403  						// check if the field is a Struct
   404  						// recursive the Struct type
   405  						if fe.Type.Kind() == reflect.Struct {
   406  							recursiveSetField(f)
   407  						}
   408  
   409  						// thanks @Gazeboxu.
   410  						tags := structTagMap[fe.Tag]
   411  						if tags == nil {
   412  							_, tags = parseStructTag(fe.Tag.Get(defaultStructTagName))
   413  							structTagMap[fe.Tag] = tags
   414  						}
   415  						var col string
   416  						if col = tags["column"]; col == "" {
   417  							col = nameStrategyMap[nameStrategy](fe.Name)
   418  						}
   419  						if v, ok := columnsMp[col]; ok {
   420  							value := reflect.ValueOf(v).Elem().Interface()
   421  							o.setFieldValue(f, value)
   422  						}
   423  					}
   424  				}
   425  
   426  				// init call the recursive function
   427  				recursiveSetField(ind)
   428  			}
   429  
   430  		} else {
   431  			if err := rows.Scan(refs...); err != nil {
   432  				return err
   433  			}
   434  
   435  			nInds := make([]reflect.Value, len(sInds))
   436  			o.loopSetRefs(refs, sInds, &nInds, eTyps, true)
   437  			for i, sInd := range sInds {
   438  				nInd := nInds[i]
   439  				sInd.Set(nInd)
   440  			}
   441  		}
   442  	} else {
   443  		return ErrNoRows
   444  	}
   445  
   446  	return nil
   447  }
   448  
   449  // query data rows and map to container
   450  func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
   451  	var (
   452  		refs  = make([]interface{}, 0, len(containers))
   453  		sInds []reflect.Value
   454  		eTyps []reflect.Type
   455  		sMi   *modelInfo
   456  	)
   457  	structMode := false
   458  	for _, container := range containers {
   459  		val := reflect.ValueOf(container)
   460  		sInd := reflect.Indirect(val)
   461  		if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice {
   462  			panic(fmt.Errorf("<RawSeter.QueryRows> all args must be use ptr slice"))
   463  		}
   464  
   465  		etyp := sInd.Type().Elem()
   466  		typ := etyp
   467  		if typ.Kind() == reflect.Ptr {
   468  			typ = typ.Elem()
   469  		}
   470  
   471  		sInds = append(sInds, sInd)
   472  		eTyps = append(eTyps, etyp)
   473  
   474  		if typ.Kind() == reflect.Struct && typ.String() != "time.Time" {
   475  			if len(containers) > 1 {
   476  				panic(fmt.Errorf("<RawSeter.QueryRow> now support one struct only. see #384"))
   477  			}
   478  
   479  			structMode = true
   480  			fn := getFullName(typ)
   481  			if mi, ok := defaultModelCache.getByFullName(fn); ok {
   482  				sMi = mi
   483  			}
   484  		} else {
   485  			var ref interface{}
   486  			refs = append(refs, &ref)
   487  		}
   488  	}
   489  
   490  	query := o.query
   491  	o.orm.alias.DbBaser.ReplaceMarks(&query)
   492  
   493  	args := getFlatParams(nil, o.args, o.orm.alias.TZ)
   494  	rows, err := o.orm.db.Query(query, args...)
   495  	if err != nil {
   496  		return 0, err
   497  	}
   498  
   499  	defer rows.Close()
   500  
   501  	var cnt int64
   502  	nInds := make([]reflect.Value, len(sInds))
   503  	sInd := sInds[0]
   504  
   505  	for rows.Next() {
   506  
   507  		if structMode {
   508  			columns, err := rows.Columns()
   509  			if err != nil {
   510  				return 0, err
   511  			}
   512  
   513  			columnsMp := make(map[string]interface{}, len(columns))
   514  
   515  			refs = make([]interface{}, 0, len(columns))
   516  			for _, col := range columns {
   517  				var ref interface{}
   518  				columnsMp[col] = &ref
   519  				refs = append(refs, &ref)
   520  			}
   521  
   522  			if err := rows.Scan(refs...); err != nil {
   523  				return 0, err
   524  			}
   525  
   526  			if cnt == 0 && !sInd.IsNil() {
   527  				sInd.Set(reflect.New(sInd.Type()).Elem())
   528  			}
   529  
   530  			var ind reflect.Value
   531  			if eTyps[0].Kind() == reflect.Ptr {
   532  				ind = reflect.New(eTyps[0].Elem())
   533  			} else {
   534  				ind = reflect.New(eTyps[0])
   535  			}
   536  
   537  			if ind.Kind() == reflect.Ptr {
   538  				ind = ind.Elem()
   539  			}
   540  
   541  			if sMi != nil {
   542  				for _, col := range columns {
   543  					if fi := sMi.fields.GetByColumn(col); fi != nil {
   544  						value := reflect.ValueOf(columnsMp[col]).Elem().Interface()
   545  						field := ind.FieldByIndex(fi.fieldIndex)
   546  						if fi.fieldType&IsRelField > 0 {
   547  							mf := reflect.New(fi.relModelInfo.addrField.Elem().Type())
   548  							field.Set(mf)
   549  							field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex)
   550  						}
   551  						if fi.isFielder {
   552  							fd := field.Addr().Interface().(Fielder)
   553  							err := fd.SetRaw(value)
   554  							if err != nil {
   555  								return 0, errors.Errorf("set raw error:%s", err)
   556  							}
   557  						} else {
   558  							o.setFieldValue(field, value)
   559  						}
   560  					}
   561  				}
   562  			} else {
   563  				// define recursive function
   564  				var recursiveSetField func(rv reflect.Value)
   565  				recursiveSetField = func(rv reflect.Value) {
   566  					for i := 0; i < rv.NumField(); i++ {
   567  						f := rv.Field(i)
   568  						fe := rv.Type().Field(i)
   569  
   570  						// check if the field is a Struct
   571  						// recursive the Struct type
   572  						if fe.Type.Kind() == reflect.Struct {
   573  							recursiveSetField(f)
   574  						}
   575  
   576  						_, tags := parseStructTag(fe.Tag.Get(defaultStructTagName))
   577  						var col string
   578  						if col = tags["column"]; col == "" {
   579  							col = nameStrategyMap[nameStrategy](fe.Name)
   580  						}
   581  						if v, ok := columnsMp[col]; ok {
   582  							value := reflect.ValueOf(v).Elem().Interface()
   583  							o.setFieldValue(f, value)
   584  						}
   585  					}
   586  				}
   587  
   588  				// init call the recursive function
   589  				recursiveSetField(ind)
   590  			}
   591  
   592  			if eTyps[0].Kind() == reflect.Ptr {
   593  				ind = ind.Addr()
   594  			}
   595  
   596  			sInd = reflect.Append(sInd, ind)
   597  
   598  		} else {
   599  			if err := rows.Scan(refs...); err != nil {
   600  				return 0, err
   601  			}
   602  
   603  			o.loopSetRefs(refs, sInds, &nInds, eTyps, cnt == 0)
   604  		}
   605  
   606  		cnt++
   607  	}
   608  
   609  	if cnt > 0 {
   610  		if structMode {
   611  			sInds[0].Set(sInd)
   612  		} else {
   613  			for i, sInd := range sInds {
   614  				nInd := nInds[i]
   615  				sInd.Set(nInd)
   616  			}
   617  		}
   618  	}
   619  
   620  	return cnt, nil
   621  }
   622  
   623  func (o *rawSet) readValues(container interface{}, needCols []string) (int64, error) {
   624  	var (
   625  		maps  []Params
   626  		lists []ParamsList
   627  		list  ParamsList
   628  	)
   629  
   630  	typ := 0
   631  	switch container.(type) {
   632  	case *[]Params:
   633  		typ = 1
   634  	case *[]ParamsList:
   635  		typ = 2
   636  	case *ParamsList:
   637  		typ = 3
   638  	default:
   639  		panic(fmt.Errorf("<RawSeter> unsupport read values type `%T`", container))
   640  	}
   641  
   642  	query := o.query
   643  	o.orm.alias.DbBaser.ReplaceMarks(&query)
   644  
   645  	args := getFlatParams(nil, o.args, o.orm.alias.TZ)
   646  
   647  	var rs *sql.Rows
   648  	rs, err := o.orm.db.Query(query, args...)
   649  	if err != nil {
   650  		return 0, err
   651  	}
   652  
   653  	defer rs.Close()
   654  
   655  	var (
   656  		refs   []interface{}
   657  		cnt    int64
   658  		cols   []string
   659  		indexs []int
   660  	)
   661  
   662  	for rs.Next() {
   663  		if cnt == 0 {
   664  			columns, err := rs.Columns()
   665  			if err != nil {
   666  				return 0, err
   667  			}
   668  			if len(needCols) > 0 {
   669  				indexs = make([]int, 0, len(needCols))
   670  			} else {
   671  				indexs = make([]int, 0, len(columns))
   672  			}
   673  
   674  			cols = columns
   675  			refs = make([]interface{}, len(cols))
   676  			for i := range refs {
   677  				var ref sql.NullString
   678  				refs[i] = &ref
   679  
   680  				if len(needCols) > 0 {
   681  					for _, c := range needCols {
   682  						if c == cols[i] {
   683  							indexs = append(indexs, i)
   684  						}
   685  					}
   686  				} else {
   687  					indexs = append(indexs, i)
   688  				}
   689  			}
   690  		}
   691  
   692  		if err := rs.Scan(refs...); err != nil {
   693  			return 0, err
   694  		}
   695  
   696  		switch typ {
   697  		case 1:
   698  			params := make(Params, len(cols))
   699  			for _, i := range indexs {
   700  				ref := refs[i]
   701  				value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString)
   702  				if value.Valid {
   703  					params[cols[i]] = value.String
   704  				} else {
   705  					params[cols[i]] = nil
   706  				}
   707  			}
   708  			maps = append(maps, params)
   709  		case 2:
   710  			params := make(ParamsList, 0, len(cols))
   711  			for _, i := range indexs {
   712  				ref := refs[i]
   713  				value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString)
   714  				if value.Valid {
   715  					params = append(params, value.String)
   716  				} else {
   717  					params = append(params, nil)
   718  				}
   719  			}
   720  			lists = append(lists, params)
   721  		case 3:
   722  			for _, i := range indexs {
   723  				ref := refs[i]
   724  				value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString)
   725  				if value.Valid {
   726  					list = append(list, value.String)
   727  				} else {
   728  					list = append(list, nil)
   729  				}
   730  			}
   731  		}
   732  
   733  		cnt++
   734  	}
   735  
   736  	switch v := container.(type) {
   737  	case *[]Params:
   738  		*v = maps
   739  	case *[]ParamsList:
   740  		*v = lists
   741  	case *ParamsList:
   742  		*v = list
   743  	}
   744  
   745  	return cnt, nil
   746  }
   747  
   748  func (o *rawSet) queryRowsTo(container interface{}, keyCol, valueCol string) (int64, error) {
   749  	var (
   750  		maps Params
   751  		ind  *reflect.Value
   752  	)
   753  
   754  	var typ int
   755  	switch container.(type) {
   756  	case *Params:
   757  		typ = 1
   758  	default:
   759  		typ = 2
   760  		vl := reflect.ValueOf(container)
   761  		id := reflect.Indirect(vl)
   762  		if vl.Kind() != reflect.Ptr || id.Kind() != reflect.Struct {
   763  			panic(fmt.Errorf("<RawSeter> RowsTo unsupport type `%T` need ptr struct", container))
   764  		}
   765  
   766  		ind = &id
   767  	}
   768  
   769  	query := o.query
   770  	o.orm.alias.DbBaser.ReplaceMarks(&query)
   771  
   772  	args := getFlatParams(nil, o.args, o.orm.alias.TZ)
   773  
   774  	rs, err := o.orm.db.Query(query, args...)
   775  	if err != nil {
   776  		return 0, err
   777  	}
   778  
   779  	defer rs.Close()
   780  
   781  	var (
   782  		refs []interface{}
   783  		cnt  int64
   784  		cols []string
   785  	)
   786  
   787  	var (
   788  		keyIndex   = -1
   789  		valueIndex = -1
   790  	)
   791  
   792  	for rs.Next() {
   793  		if cnt == 0 {
   794  			columns, err := rs.Columns()
   795  			if err != nil {
   796  				return 0, err
   797  			}
   798  			cols = columns
   799  			refs = make([]interface{}, len(cols))
   800  			for i := range refs {
   801  				if keyCol == cols[i] {
   802  					keyIndex = i
   803  				}
   804  				if typ == 1 || keyIndex == i {
   805  					var ref sql.NullString
   806  					refs[i] = &ref
   807  				} else {
   808  					var ref interface{}
   809  					refs[i] = &ref
   810  				}
   811  				if valueCol == cols[i] {
   812  					valueIndex = i
   813  				}
   814  			}
   815  			if keyIndex == -1 || valueIndex == -1 {
   816  				panic(fmt.Errorf("<RawSeter> RowsTo unknown key, value column name `%s: %s`", keyCol, valueCol))
   817  			}
   818  		}
   819  
   820  		if err := rs.Scan(refs...); err != nil {
   821  			return 0, err
   822  		}
   823  
   824  		if cnt == 0 {
   825  			switch typ {
   826  			case 1:
   827  				maps = make(Params)
   828  			}
   829  		}
   830  
   831  		key := reflect.Indirect(reflect.ValueOf(refs[keyIndex])).Interface().(sql.NullString).String
   832  
   833  		switch typ {
   834  		case 1:
   835  			value := reflect.Indirect(reflect.ValueOf(refs[valueIndex])).Interface().(sql.NullString)
   836  			if value.Valid {
   837  				maps[key] = value.String
   838  			} else {
   839  				maps[key] = nil
   840  			}
   841  
   842  		default:
   843  			if id := ind.FieldByName(camelString(key)); id.IsValid() {
   844  				o.setFieldValue(id, reflect.ValueOf(refs[valueIndex]).Elem().Interface())
   845  			}
   846  		}
   847  
   848  		cnt++
   849  	}
   850  
   851  	if typ == 1 {
   852  		v, _ := container.(*Params)
   853  		*v = maps
   854  	}
   855  
   856  	return cnt, nil
   857  }
   858  
   859  // query data to []map[string]interface
   860  func (o *rawSet) Values(container *[]Params, cols ...string) (int64, error) {
   861  	return o.readValues(container, cols)
   862  }
   863  
   864  // query data to [][]interface
   865  func (o *rawSet) ValuesList(container *[]ParamsList, cols ...string) (int64, error) {
   866  	return o.readValues(container, cols)
   867  }
   868  
   869  // query data to []interface
   870  func (o *rawSet) ValuesFlat(container *ParamsList, cols ...string) (int64, error) {
   871  	return o.readValues(container, cols)
   872  }
   873  
   874  // query all rows into map[string]interface with specify key and value column name.
   875  // keyCol = "name", valueCol = "value"
   876  // table data
   877  // name  | value
   878  // total | 100
   879  // found | 200
   880  //
   881  //	to map[string]interface{}{
   882  //		"total": 100,
   883  //		"found": 200,
   884  //	}
   885  func (o *rawSet) RowsToMap(result *Params, keyCol, valueCol string) (int64, error) {
   886  	return o.queryRowsTo(result, keyCol, valueCol)
   887  }
   888  
   889  // query all rows into struct with specify key and value column name.
   890  // keyCol = "name", valueCol = "value"
   891  // table data
   892  // name  | value
   893  // total | 100
   894  // found | 200
   895  //
   896  //	to struct {
   897  //		Total int
   898  //		Found int
   899  //	}
   900  func (o *rawSet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) {
   901  	return o.queryRowsTo(ptrStruct, keyCol, valueCol)
   902  }
   903  
   904  // return prepared raw statement for used in times.
   905  func (o *rawSet) Prepare() (RawPreparer, error) {
   906  	return newRawPreparer(o)
   907  }
   908  
   909  func newRawSet(orm *ormBase, query string, args []interface{}) RawSeter {
   910  	o := new(rawSet)
   911  	o.query = query
   912  	o.args = args
   913  	o.orm = orm
   914  	return o
   915  }