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

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"strings"
     7  	"time"
     8  )
     9  
    10  const (
    11  	TWOSIDES = iota + 1
    12  	ONLYTODB
    13  	ONLYFROMDB
    14  )
    15  
    16  // database column
    17  type Column struct {
    18  	Name            string
    19  	TableName       string
    20  	FieldName       string
    21  	SQLType         SQLType
    22  	Length          int
    23  	Length2         int
    24  	Nullable        bool
    25  	Default         string
    26  	Indexes         map[string]int
    27  	IsPrimaryKey    bool
    28  	IsAutoIncrement bool
    29  	MapType         int
    30  	IsCreated       bool
    31  	IsUpdated       bool
    32  	IsDeleted       bool
    33  	IsCascade       bool
    34  	IsVersion       bool
    35  	fieldPath       []string
    36  	DefaultIsEmpty  bool
    37  	EnumOptions     map[string]int
    38  	SetOptions      map[string]int
    39  	DisableTimeZone bool
    40  	TimeZone        *time.Location // column specified time zone
    41  }
    42  
    43  func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
    44  	return &Column{
    45  		Name:            name,
    46  		TableName:       "",
    47  		FieldName:       fieldName,
    48  		SQLType:         sqlType,
    49  		Length:          len1,
    50  		Length2:         len2,
    51  		Nullable:        nullable,
    52  		Default:         "",
    53  		Indexes:         make(map[string]int),
    54  		IsPrimaryKey:    false,
    55  		IsAutoIncrement: false,
    56  		MapType:         TWOSIDES,
    57  		IsCreated:       false,
    58  		IsUpdated:       false,
    59  		IsDeleted:       false,
    60  		IsCascade:       false,
    61  		IsVersion:       false,
    62  		fieldPath:       nil,
    63  		DefaultIsEmpty:  false,
    64  		EnumOptions:     make(map[string]int),
    65  	}
    66  }
    67  
    68  // generate column description string according dialect
    69  func (col *Column) String(d Dialect) string {
    70  	sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
    71  
    72  	sql += d.SqlType(col) + " "
    73  
    74  	if col.IsPrimaryKey {
    75  		sql += "PRIMARY KEY "
    76  		if col.IsAutoIncrement {
    77  			sql += d.AutoIncrStr() + " "
    78  		}
    79  	}
    80  
    81  	if d.ShowCreateNull() {
    82  		if col.Nullable {
    83  			sql += "NULL "
    84  		} else {
    85  			sql += "NOT NULL "
    86  		}
    87  	}
    88  
    89  	if col.Default != "" {
    90  		sql += "DEFAULT " + col.Default + " "
    91  	}
    92  
    93  	return sql
    94  }
    95  
    96  func (col *Column) StringNoPk(d Dialect) string {
    97  	sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
    98  
    99  	sql += d.SqlType(col) + " "
   100  
   101  	if d.ShowCreateNull() {
   102  		if col.Nullable {
   103  			sql += "NULL "
   104  		} else {
   105  			sql += "NOT NULL "
   106  		}
   107  	}
   108  
   109  	if col.Default != "" {
   110  		sql += "DEFAULT " + col.Default + " "
   111  	}
   112  
   113  	return sql
   114  }
   115  
   116  // return col's filed of struct's value
   117  func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
   118  	dataStruct := reflect.Indirect(reflect.ValueOf(bean))
   119  	return col.ValueOfV(&dataStruct)
   120  }
   121  
   122  func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
   123  	var fieldValue reflect.Value
   124  	if col.fieldPath == nil {
   125  		col.fieldPath = strings.Split(col.FieldName, ".")
   126  	}
   127  
   128  	if dataStruct.Type().Kind() == reflect.Map {
   129  		keyValue := reflect.ValueOf(col.fieldPath[len(col.fieldPath)-1])
   130  		fieldValue = dataStruct.MapIndex(keyValue)
   131  		return &fieldValue, nil
   132  	} else if dataStruct.Type().Kind() == reflect.Interface {
   133  		structValue := reflect.ValueOf(dataStruct.Interface())
   134  		dataStruct = &structValue
   135  	}
   136  
   137  	level := len(col.fieldPath)
   138  	fieldValue = dataStruct.FieldByName(col.fieldPath[0])
   139  	for i := 0; i < level-1; i++ {
   140  		if !fieldValue.IsValid() {
   141  			break
   142  		}
   143  		if fieldValue.Kind() == reflect.Struct {
   144  			fieldValue = fieldValue.FieldByName(col.fieldPath[i+1])
   145  		} else if fieldValue.Kind() == reflect.Ptr {
   146  			if fieldValue.IsNil() {
   147  				fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
   148  			}
   149  			fieldValue = fieldValue.Elem().FieldByName(col.fieldPath[i+1])
   150  		} else {
   151  			return nil, fmt.Errorf("field  %v is not valid", col.FieldName)
   152  		}
   153  	}
   154  
   155  	if !fieldValue.IsValid() {
   156  		return nil, fmt.Errorf("field  %v is not valid", col.FieldName)
   157  	}
   158  
   159  	return &fieldValue, nil
   160  }