github.com/astaxie/beego@v1.12.3/orm/db_utils.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package orm
    16  
    17  import (
    18  	"fmt"
    19  	"reflect"
    20  	"time"
    21  )
    22  
    23  // get table alias.
    24  func getDbAlias(name string) *alias {
    25  	if al, ok := dataBaseCache.get(name); ok {
    26  		return al
    27  	}
    28  	panic(fmt.Errorf("unknown DataBase alias name %s", name))
    29  }
    30  
    31  // get pk column info.
    32  func getExistPk(mi *modelInfo, ind reflect.Value) (column string, value interface{}, exist bool) {
    33  	fi := mi.fields.pk
    34  
    35  	v := ind.FieldByIndex(fi.fieldIndex)
    36  	if fi.fieldType&IsPositiveIntegerField > 0 {
    37  		vu := v.Uint()
    38  		exist = vu > 0
    39  		value = vu
    40  	} else if fi.fieldType&IsIntegerField > 0 {
    41  		vu := v.Int()
    42  		exist = true
    43  		value = vu
    44  	} else if fi.fieldType&IsRelField > 0 {
    45  		_, value, exist = getExistPk(fi.relModelInfo, reflect.Indirect(v))
    46  	} else {
    47  		vu := v.String()
    48  		exist = vu != ""
    49  		value = vu
    50  	}
    51  
    52  	column = fi.column
    53  	return
    54  }
    55  
    56  // get fields description as flatted string.
    57  func getFlatParams(fi *fieldInfo, args []interface{}, tz *time.Location) (params []interface{}) {
    58  
    59  outFor:
    60  	for _, arg := range args {
    61  		val := reflect.ValueOf(arg)
    62  
    63  		if arg == nil {
    64  			params = append(params, arg)
    65  			continue
    66  		}
    67  
    68  		kind := val.Kind()
    69  		if kind == reflect.Ptr {
    70  			val = val.Elem()
    71  			kind = val.Kind()
    72  			arg = val.Interface()
    73  		}
    74  
    75  		switch kind {
    76  		case reflect.String:
    77  			v := val.String()
    78  			if fi != nil {
    79  				if fi.fieldType == TypeTimeField || fi.fieldType == TypeDateField || fi.fieldType == TypeDateTimeField {
    80  					var t time.Time
    81  					var err error
    82  					if len(v) >= 19 {
    83  						s := v[:19]
    84  						t, err = time.ParseInLocation(formatDateTime, s, DefaultTimeLoc)
    85  					} else if len(v) >= 10 {
    86  						s := v
    87  						if len(v) > 10 {
    88  							s = v[:10]
    89  						}
    90  						t, err = time.ParseInLocation(formatDate, s, tz)
    91  					} else {
    92  						s := v
    93  						if len(s) > 8 {
    94  							s = v[:8]
    95  						}
    96  						t, err = time.ParseInLocation(formatTime, s, tz)
    97  					}
    98  					if err == nil {
    99  						if fi.fieldType == TypeDateField {
   100  							v = t.In(tz).Format(formatDate)
   101  						} else if fi.fieldType == TypeDateTimeField {
   102  							v = t.In(tz).Format(formatDateTime)
   103  						} else {
   104  							v = t.In(tz).Format(formatTime)
   105  						}
   106  					}
   107  				}
   108  			}
   109  			arg = v
   110  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   111  			arg = val.Int()
   112  		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   113  			arg = val.Uint()
   114  		case reflect.Float32:
   115  			arg, _ = StrTo(ToStr(arg)).Float64()
   116  		case reflect.Float64:
   117  			arg = val.Float()
   118  		case reflect.Bool:
   119  			arg = val.Bool()
   120  		case reflect.Slice, reflect.Array:
   121  			if _, ok := arg.([]byte); ok {
   122  				continue outFor
   123  			}
   124  
   125  			var args []interface{}
   126  			for i := 0; i < val.Len(); i++ {
   127  				v := val.Index(i)
   128  
   129  				var vu interface{}
   130  				if v.CanInterface() {
   131  					vu = v.Interface()
   132  				}
   133  
   134  				if vu == nil {
   135  					continue
   136  				}
   137  
   138  				args = append(args, vu)
   139  			}
   140  
   141  			if len(args) > 0 {
   142  				p := getFlatParams(fi, args, tz)
   143  				params = append(params, p...)
   144  			}
   145  			continue outFor
   146  		case reflect.Struct:
   147  			if v, ok := arg.(time.Time); ok {
   148  				if fi != nil && fi.fieldType == TypeDateField {
   149  					arg = v.In(tz).Format(formatDate)
   150  				} else if fi != nil && fi.fieldType == TypeDateTimeField {
   151  					arg = v.In(tz).Format(formatDateTime)
   152  				} else if fi != nil && fi.fieldType == TypeTimeField {
   153  					arg = v.In(tz).Format(formatTime)
   154  				} else {
   155  					arg = v.In(tz).Format(formatDateTime)
   156  				}
   157  			} else {
   158  				typ := val.Type()
   159  				name := getFullName(typ)
   160  				var value interface{}
   161  				if mmi, ok := modelCache.getByFullName(name); ok {
   162  					if _, vu, exist := getExistPk(mmi, val); exist {
   163  						value = vu
   164  					}
   165  				}
   166  				arg = value
   167  
   168  				if arg == nil {
   169  					panic(fmt.Errorf("need a valid args value, unknown table or value `%s`", name))
   170  				}
   171  			}
   172  		}
   173  
   174  		params = append(params, arg)
   175  	}
   176  	return
   177  }