1. 实现配置文件解析
2. 实现数据库连接
This commit is contained in:
213
vendor/gorm.io/gorm/schema/utils.go
generated
vendored
Normal file
213
vendor/gorm.io/gorm/schema/utils.go
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm/clause"
|
||||
"gorm.io/gorm/utils"
|
||||
)
|
||||
|
||||
var embeddedCacheKey = "embedded_cache_store"
|
||||
|
||||
func ParseTagSetting(str string, sep string) map[string]string {
|
||||
settings := map[string]string{}
|
||||
names := strings.Split(str, sep)
|
||||
|
||||
for i := 0; i < len(names); i++ {
|
||||
j := i
|
||||
if len(names[j]) > 0 {
|
||||
for {
|
||||
if names[j][len(names[j])-1] == '\\' {
|
||||
i++
|
||||
names[j] = names[j][0:len(names[j])-1] + sep + names[i]
|
||||
names[i] = ""
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
values := strings.Split(names[j], ":")
|
||||
k := strings.TrimSpace(strings.ToUpper(values[0]))
|
||||
|
||||
if len(values) >= 2 {
|
||||
settings[k] = strings.Join(values[1:], ":")
|
||||
} else if k != "" {
|
||||
settings[k] = k
|
||||
}
|
||||
}
|
||||
|
||||
return settings
|
||||
}
|
||||
|
||||
func toColumns(val string) (results []string) {
|
||||
if val != "" {
|
||||
for _, v := range strings.Split(val, ",") {
|
||||
results = append(results, strings.TrimSpace(v))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func removeSettingFromTag(tag reflect.StructTag, names ...string) reflect.StructTag {
|
||||
for _, name := range names {
|
||||
tag = reflect.StructTag(regexp.MustCompile(`(?i)(gorm:.*?)(`+name+`(:.*?)?)(;|("))`).ReplaceAllString(string(tag), "${1}${5}"))
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
func appendSettingFromTag(tag reflect.StructTag, value string) reflect.StructTag {
|
||||
t := tag.Get("gorm")
|
||||
if strings.Contains(t, value) {
|
||||
return tag
|
||||
}
|
||||
return reflect.StructTag(fmt.Sprintf(`gorm:"%s;%s"`, value, t))
|
||||
}
|
||||
|
||||
// GetRelationsValues get relations's values from a reflect value
|
||||
func GetRelationsValues(ctx context.Context, reflectValue reflect.Value, rels []*Relationship) (reflectResults reflect.Value) {
|
||||
for _, rel := range rels {
|
||||
reflectResults = reflect.MakeSlice(reflect.SliceOf(reflect.PtrTo(rel.FieldSchema.ModelType)), 0, 1)
|
||||
|
||||
appendToResults := func(value reflect.Value) {
|
||||
if _, isZero := rel.Field.ValueOf(ctx, value); !isZero {
|
||||
result := reflect.Indirect(rel.Field.ReflectValueOf(ctx, value))
|
||||
switch result.Kind() {
|
||||
case reflect.Struct:
|
||||
reflectResults = reflect.Append(reflectResults, result.Addr())
|
||||
case reflect.Slice, reflect.Array:
|
||||
for i := 0; i < result.Len(); i++ {
|
||||
if elem := result.Index(i); elem.Kind() == reflect.Ptr {
|
||||
reflectResults = reflect.Append(reflectResults, elem)
|
||||
} else {
|
||||
reflectResults = reflect.Append(reflectResults, elem.Addr())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch reflectValue.Kind() {
|
||||
case reflect.Struct:
|
||||
appendToResults(reflectValue)
|
||||
case reflect.Slice:
|
||||
for i := 0; i < reflectValue.Len(); i++ {
|
||||
appendToResults(reflectValue.Index(i))
|
||||
}
|
||||
}
|
||||
|
||||
reflectValue = reflectResults
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetIdentityFieldValuesMap get identity map from fields
|
||||
func GetIdentityFieldValuesMap(ctx context.Context, reflectValue reflect.Value, fields []*Field) (map[string][]reflect.Value, [][]interface{}) {
|
||||
var (
|
||||
results = [][]interface{}{}
|
||||
dataResults = map[string][]reflect.Value{}
|
||||
loaded = map[interface{}]bool{}
|
||||
notZero, zero bool
|
||||
)
|
||||
|
||||
if reflectValue.Kind() == reflect.Ptr ||
|
||||
reflectValue.Kind() == reflect.Interface {
|
||||
reflectValue = reflectValue.Elem()
|
||||
}
|
||||
|
||||
switch reflectValue.Kind() {
|
||||
case reflect.Struct:
|
||||
results = [][]interface{}{make([]interface{}, len(fields))}
|
||||
|
||||
for idx, field := range fields {
|
||||
results[0][idx], zero = field.ValueOf(ctx, reflectValue)
|
||||
notZero = notZero || !zero
|
||||
}
|
||||
|
||||
if !notZero {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
dataResults[utils.ToStringKey(results[0]...)] = []reflect.Value{reflectValue}
|
||||
case reflect.Slice, reflect.Array:
|
||||
for i := 0; i < reflectValue.Len(); i++ {
|
||||
elem := reflectValue.Index(i)
|
||||
elemKey := elem.Interface()
|
||||
if elem.Kind() != reflect.Ptr && elem.CanAddr() {
|
||||
elemKey = elem.Addr().Interface()
|
||||
}
|
||||
|
||||
if _, ok := loaded[elemKey]; ok {
|
||||
continue
|
||||
}
|
||||
loaded[elemKey] = true
|
||||
|
||||
fieldValues := make([]interface{}, len(fields))
|
||||
notZero = false
|
||||
for idx, field := range fields {
|
||||
fieldValues[idx], zero = field.ValueOf(ctx, elem)
|
||||
notZero = notZero || !zero
|
||||
}
|
||||
|
||||
if notZero {
|
||||
dataKey := utils.ToStringKey(fieldValues...)
|
||||
if _, ok := dataResults[dataKey]; !ok {
|
||||
results = append(results, fieldValues)
|
||||
dataResults[dataKey] = []reflect.Value{elem}
|
||||
} else {
|
||||
dataResults[dataKey] = append(dataResults[dataKey], elem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dataResults, results
|
||||
}
|
||||
|
||||
// GetIdentityFieldValuesMapFromValues get identity map from fields
|
||||
func GetIdentityFieldValuesMapFromValues(ctx context.Context, values []interface{}, fields []*Field) (map[string][]reflect.Value, [][]interface{}) {
|
||||
resultsMap := map[string][]reflect.Value{}
|
||||
results := [][]interface{}{}
|
||||
|
||||
for _, v := range values {
|
||||
rm, rs := GetIdentityFieldValuesMap(ctx, reflect.Indirect(reflect.ValueOf(v)), fields)
|
||||
for k, v := range rm {
|
||||
resultsMap[k] = append(resultsMap[k], v...)
|
||||
}
|
||||
results = append(results, rs...)
|
||||
}
|
||||
return resultsMap, results
|
||||
}
|
||||
|
||||
// ToQueryValues to query values
|
||||
func ToQueryValues(table string, foreignKeys []string, foreignValues [][]interface{}) (interface{}, []interface{}) {
|
||||
queryValues := make([]interface{}, len(foreignValues))
|
||||
if len(foreignKeys) == 1 {
|
||||
for idx, r := range foreignValues {
|
||||
queryValues[idx] = r[0]
|
||||
}
|
||||
|
||||
return clause.Column{Table: table, Name: foreignKeys[0]}, queryValues
|
||||
}
|
||||
|
||||
columns := make([]clause.Column, len(foreignKeys))
|
||||
for idx, key := range foreignKeys {
|
||||
columns[idx] = clause.Column{Table: table, Name: key}
|
||||
}
|
||||
|
||||
for idx, r := range foreignValues {
|
||||
queryValues[idx] = r
|
||||
}
|
||||
|
||||
return columns, queryValues
|
||||
}
|
||||
|
||||
type embeddedNamer struct {
|
||||
Table string
|
||||
Namer
|
||||
}
|
||||
Reference in New Issue
Block a user