You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.2 KiB
118 lines
3.2 KiB
5 years ago
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
5 years ago
|
package schemas
|
||
8 years ago
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
TWOSIDES = iota + 1
|
||
|
ONLYTODB
|
||
|
ONLYFROMDB
|
||
|
)
|
||
|
|
||
7 years ago
|
// Column defines database column
|
||
8 years ago
|
type Column struct {
|
||
|
Name string
|
||
|
TableName string
|
||
5 years ago
|
FieldName string // Avaiable only when parsed from a struct
|
||
8 years ago
|
SQLType SQLType
|
||
7 years ago
|
IsJSON bool
|
||
8 years ago
|
Length int
|
||
|
Length2 int
|
||
|
Nullable bool
|
||
|
Default string
|
||
|
Indexes map[string]int
|
||
|
IsPrimaryKey bool
|
||
|
IsAutoIncrement bool
|
||
|
MapType int
|
||
|
IsCreated bool
|
||
|
IsUpdated bool
|
||
|
IsDeleted bool
|
||
|
IsCascade bool
|
||
|
IsVersion bool
|
||
5 years ago
|
DefaultIsEmpty bool // false means column has no default set, but not default value is empty
|
||
8 years ago
|
EnumOptions map[string]int
|
||
|
SetOptions map[string]int
|
||
|
DisableTimeZone bool
|
||
|
TimeZone *time.Location // column specified time zone
|
||
7 years ago
|
Comment string
|
||
8 years ago
|
}
|
||
|
|
||
5 years ago
|
// NewColumn creates a new column
|
||
8 years ago
|
func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
|
||
|
return &Column{
|
||
|
Name: name,
|
||
|
TableName: "",
|
||
|
FieldName: fieldName,
|
||
|
SQLType: sqlType,
|
||
|
Length: len1,
|
||
|
Length2: len2,
|
||
|
Nullable: nullable,
|
||
|
Default: "",
|
||
|
Indexes: make(map[string]int),
|
||
|
IsPrimaryKey: false,
|
||
|
IsAutoIncrement: false,
|
||
|
MapType: TWOSIDES,
|
||
|
IsCreated: false,
|
||
|
IsUpdated: false,
|
||
|
IsDeleted: false,
|
||
|
IsCascade: false,
|
||
|
IsVersion: false,
|
||
5 years ago
|
DefaultIsEmpty: true, // default should be no default
|
||
8 years ago
|
EnumOptions: make(map[string]int),
|
||
7 years ago
|
Comment: "",
|
||
8 years ago
|
}
|
||
|
}
|
||
|
|
||
5 years ago
|
// ValueOf returns column's filed of struct's value
|
||
8 years ago
|
func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
|
||
|
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
|
||
|
return col.ValueOfV(&dataStruct)
|
||
|
}
|
||
|
|
||
5 years ago
|
// ValueOfV returns column's filed of struct's value accept reflevt value
|
||
8 years ago
|
func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||
|
var fieldValue reflect.Value
|
||
8 years ago
|
fieldPath := strings.Split(col.FieldName, ".")
|
||
8 years ago
|
|
||
|
if dataStruct.Type().Kind() == reflect.Map {
|
||
8 years ago
|
keyValue := reflect.ValueOf(fieldPath[len(fieldPath)-1])
|
||
8 years ago
|
fieldValue = dataStruct.MapIndex(keyValue)
|
||
|
return &fieldValue, nil
|
||
|
} else if dataStruct.Type().Kind() == reflect.Interface {
|
||
|
structValue := reflect.ValueOf(dataStruct.Interface())
|
||
|
dataStruct = &structValue
|
||
|
}
|
||
|
|
||
8 years ago
|
level := len(fieldPath)
|
||
|
fieldValue = dataStruct.FieldByName(fieldPath[0])
|
||
8 years ago
|
for i := 0; i < level-1; i++ {
|
||
|
if !fieldValue.IsValid() {
|
||
|
break
|
||
|
}
|
||
|
if fieldValue.Kind() == reflect.Struct {
|
||
8 years ago
|
fieldValue = fieldValue.FieldByName(fieldPath[i+1])
|
||
8 years ago
|
} else if fieldValue.Kind() == reflect.Ptr {
|
||
|
if fieldValue.IsNil() {
|
||
|
fieldValue.Set(reflect.New(fieldValue.Type().Elem()))
|
||
|
}
|
||
8 years ago
|
fieldValue = fieldValue.Elem().FieldByName(fieldPath[i+1])
|
||
8 years ago
|
} else {
|
||
6 years ago
|
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||
8 years ago
|
}
|
||
|
}
|
||
|
|
||
|
if !fieldValue.IsValid() {
|
||
6 years ago
|
return nil, fmt.Errorf("field %v is not valid", col.FieldName)
|
||
8 years ago
|
}
|
||
|
|
||
|
return &fieldValue, nil
|
||
|
}
|