github.com/zhongdalu/gf@v1.0.0/g/database/gdb/gdb_structure.go (about) 1 // Copyright 2019 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/zhongdalu/gf. 6 7 package gdb 8 9 import ( 10 "fmt" 11 "strings" 12 13 "github.com/zhongdalu/gf/g/encoding/gbinary" 14 15 "github.com/zhongdalu/gf/g/text/gregex" 16 "github.com/zhongdalu/gf/g/util/gconv" 17 ) 18 19 //// 同步数据库表结构到内存中 20 //func (bs *dbBase) syncTableStructure() { 21 // bs.tables = make(map[string]map[string]string) 22 // for _, table := range bs.db.getTables() { 23 // bs.tables[table], _ = bs.db.getTableFields(table) 24 // } 25 //} 26 27 // 字段类型转换,将数据库字段类型转换为golang变量类型 28 func (bs *dbBase) convertValue(fieldValue []byte, fieldType string) interface{} { 29 t, _ := gregex.ReplaceString(`\(.+\)`, "", fieldType) 30 t = strings.ToLower(t) 31 switch t { 32 case "binary", "varbinary", "blob", "tinyblob", "mediumblob", "longblob": 33 return fieldValue 34 35 case "int", "tinyint", "small_int", "medium_int": 36 return gconv.Int(string(fieldValue)) 37 38 case "big_int": 39 return gconv.Int64(string(fieldValue)) 40 41 case "float", "double", "decimal": 42 return gconv.Float64(string(fieldValue)) 43 44 case "bit": 45 s := string(fieldValue) 46 // 这里的字符串判断是为兼容不同的数据库类型,如: mssql 47 if strings.EqualFold(s, "true") { 48 return 1 49 } 50 if strings.EqualFold(s, "false") { 51 return 0 52 } 53 return gbinary.BeDecodeToInt64(fieldValue) 54 55 case "bool": 56 return gconv.Bool(fieldValue) 57 58 default: 59 // 自动识别类型, 以便默认支持更多数据库类型 60 switch { 61 case strings.Contains(t, "int"): 62 return gconv.Int(string(fieldValue)) 63 64 case strings.Contains(t, "text") || strings.Contains(t, "char"): 65 return string(fieldValue) 66 67 case strings.Contains(t, "float") || strings.Contains(t, "double"): 68 return gconv.Float64(string(fieldValue)) 69 70 case strings.Contains(t, "bool"): 71 return gconv.Bool(string(fieldValue)) 72 73 case strings.Contains(t, "binary") || strings.Contains(t, "blob"): 74 return fieldValue 75 76 default: 77 return string(fieldValue) 78 } 79 } 80 } 81 82 // 将map的数据按照fields进行过滤,只保留与表字段同名的数据 83 func (bs *dbBase) filterFields(table string, data map[string]interface{}) map[string]interface{} { 84 if fields, err := bs.db.getTableFields(table); err == nil { 85 for k, _ := range data { 86 if _, ok := fields[k]; !ok { 87 delete(data, k) 88 } 89 } 90 } 91 return data 92 } 93 94 // 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值暂无用途(默认为字段数据类型). 95 func (bs *dbBase) getTableFields(table string) (fields map[string]string, err error) { 96 // 缓存不存在时会查询数据表结构,缓存后不过期,直至程序重启(重新部署) 97 v := bs.cache.GetOrSetFunc("table_fields_"+table, func() interface{} { 98 result := (Result)(nil) 99 result, err = bs.GetAll(fmt.Sprintf(`SHOW COLUMNS FROM %s`, bs.db.quoteWord(table))) 100 if err != nil { 101 return nil 102 } 103 fields = make(map[string]string) 104 for _, m := range result { 105 fields[m["Field"].String()] = m["Type"].String() 106 } 107 return fields 108 }, 0) 109 if err == nil { 110 fields = v.(map[string]string) 111 } 112 return 113 } 114 115 /* 116 // 获取当前数据库所有的表结构 117 func (bs *dbBase) getTables() []string { 118 if result, _ := bs.GetAll(`SHOW TABLES`); result != nil { 119 array := make([]string, len(result)) 120 for i, m := range result { 121 for _, v := range m { 122 array[i] = v.String() 123 break 124 } 125 } 126 return array 127 } 128 return nil 129 } 130 */