mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve gconv.Bool for NO/YES; improve gdb for model generation
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
|
||||
# MySQL数据库配置
|
||||
[database]
|
||||
link = "mysql:luoling2013:m5k2s8p5@tcp(127.0.0.1:3306)/test"
|
||||
link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
|
||||
|
||||
|
||||
18
.example/database/gdb/mysql/gdb_tables.go
Normal file
18
.example/database/gdb/mysql/gdb_tables.go
Normal file
@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db := g.DB()
|
||||
db.SetDebug(true)
|
||||
|
||||
tables, err := db.Tables()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if tables != nil {
|
||||
g.Dump(tables)
|
||||
}
|
||||
}
|
||||
25
.example/database/gdb/mysql/gdb_tables_fields.go
Normal file
25
.example/database/gdb/mysql/gdb_tables_fields.go
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
)
|
||||
|
||||
func main() {
|
||||
db := g.DB()
|
||||
db.SetDebug(true)
|
||||
|
||||
tables, e := db.Tables()
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
if tables != nil {
|
||||
g.Dump(tables)
|
||||
for _, table := range tables {
|
||||
fields, err := db.TableFields(table)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
g.Dump(fields)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,8 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/database/gdb"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
)
|
||||
import "github.com/gogf/gf/database/gdb"
|
||||
|
||||
func DB() gdb.DB {
|
||||
return g.DB()
|
||||
}
|
||||
var (
|
||||
// ConfigGroup is the configuration group name for this model.
|
||||
ConfigGroup = gdb.DEFAULT_GROUP_NAME
|
||||
)
|
||||
|
||||
@ -3,13 +3,13 @@ package test
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"github.com/gogf/gf/debug/gdebug"
|
||||
"github.com/gogf/gf/frame/gins"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
|
||||
"github.com/gogf/gf/database/gdb"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
)
|
||||
|
||||
// User is the golang structure for table user.
|
||||
type User struct {
|
||||
Id int `orm:"id,primary" json:"id"`
|
||||
Passport string `orm:"passport" json:"passport"`
|
||||
@ -18,50 +18,59 @@ type User struct {
|
||||
CreateTime *gtime.Time `orm:"create_time" json:"create_time"`
|
||||
}
|
||||
|
||||
// UserModel is the model of convenient operations for table user.
|
||||
type UserModel struct {
|
||||
*gdb.Model
|
||||
TableName string
|
||||
}
|
||||
|
||||
var (
|
||||
UserTableName = "user"
|
||||
gUserModelCacheKey = gdebug.CallerFilePath()
|
||||
// UserTableName is the table name of user.
|
||||
UserTableName = "user"
|
||||
)
|
||||
|
||||
// ModelUser creates and returns a new model object for table user.
|
||||
func ModelUser() *UserModel {
|
||||
return gins.GetOrSetFunc(gUserModelCacheKey, func() interface{} {
|
||||
return &UserModel{
|
||||
DB().Table(UserTableName).Safe(),
|
||||
UserTableName,
|
||||
}
|
||||
}).(*UserModel)
|
||||
return &UserModel{
|
||||
g.DB(ConfigGroup).Table(UserTableName).Safe(),
|
||||
UserTableName,
|
||||
}
|
||||
}
|
||||
|
||||
// Inserts does "INSERT...INTO..." statement for inserting current object into table.
|
||||
func (r *User) Insert() (result sql.Result, err error) {
|
||||
return ModelUser().Data(r).Insert()
|
||||
}
|
||||
|
||||
// Replace does "REPLACE...INTO..." statement for inserting current object into table.
|
||||
// If there's already another same record in the table (it checks using primary key or unique index),
|
||||
// it deletes it and insert this one.
|
||||
func (r *User) Replace() (result sql.Result, err error) {
|
||||
return ModelUser().Data(r).Replace()
|
||||
}
|
||||
|
||||
// Save does "INSERT...INTO..." statement for inserting/updating current object into table.
|
||||
// It updates the record if there's already another same record in the table
|
||||
// (it checks using primary key or unique index).
|
||||
func (r *User) Save() (result sql.Result, err error) {
|
||||
return ModelUser().Data(r).Save()
|
||||
}
|
||||
|
||||
// Update does "UPDATE...WHERE..." statement for updating current object from table.
|
||||
// It updates the record if there's already another same record in the table
|
||||
// (it checks using primary key or unique index).
|
||||
func (r *User) Update() (result sql.Result, err error) {
|
||||
return ModelUser().Data(r).Where(gdb.GetWhereConditionOfStruct(r)).Update()
|
||||
}
|
||||
|
||||
// Delete does "DELETE FROM...WHERE..." statement for deleting current object from table.
|
||||
func (r *User) Delete() (result sql.Result, err error) {
|
||||
return ModelUser().Where(gdb.GetWhereConditionOfStruct(r)).Delete()
|
||||
}
|
||||
|
||||
// Select overwrite the Select method from gdb.Model for model
|
||||
// as retuning all objects with specified structure.
|
||||
func (m *UserModel) Select() ([]*User, error) {
|
||||
return m.All()
|
||||
}
|
||||
|
||||
func (m *UserModel) All() ([]*User, error) {
|
||||
array := ([]*User)(nil)
|
||||
if err := m.Scan(&array); err != nil {
|
||||
return nil, err
|
||||
@ -69,8 +78,10 @@ func (m *UserModel) All() ([]*User, error) {
|
||||
return array, nil
|
||||
}
|
||||
|
||||
func (m *UserModel) One() (*User, error) {
|
||||
list, err := m.All()
|
||||
// First does the same logistics as One method from gdb.Model for model
|
||||
// as retuning first/one object with specified structure.
|
||||
func (m *UserModel) First() (*User, error) {
|
||||
list, err := m.Select()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -91,6 +91,8 @@ type DB interface {
|
||||
SetMaxIdleConnCount(n int)
|
||||
SetMaxOpenConnCount(n int)
|
||||
SetMaxConnLifetime(n int)
|
||||
Tables() (tables []string, err error)
|
||||
TableFields(table string) (map[string]*TableField, error)
|
||||
|
||||
// 内部方法接口
|
||||
getCache() *gcache.Cache
|
||||
@ -101,7 +103,6 @@ type DB interface {
|
||||
filterFields(table string, data map[string]interface{}) map[string]interface{}
|
||||
formatWhere(where interface{}, args []interface{}) (newWhere string, newArgs []interface{})
|
||||
convertValue(fieldValue []byte, fieldType string) interface{}
|
||||
getTableFields(table string) (map[string]string, error)
|
||||
rowsToResult(rows *sql.Rows) (Result, error)
|
||||
handleSqlBeforeExec(sql string) string
|
||||
}
|
||||
@ -137,6 +138,17 @@ type Sql struct {
|
||||
End int64 // 执行结束时间(毫秒)
|
||||
}
|
||||
|
||||
// 表字段结构信息
|
||||
type TableField struct {
|
||||
Index int // 用于字段排序(map类型是无序的)
|
||||
Name string // 字段名称
|
||||
Type string // 字段类型
|
||||
Null bool // 是否可为null
|
||||
Key string // 索引信息
|
||||
Default interface{} // 默认值
|
||||
Extra string // 其他信息
|
||||
}
|
||||
|
||||
// 返回数据表记录值
|
||||
type Value = *gvar.Var
|
||||
|
||||
|
||||
@ -14,9 +14,10 @@ package gdb
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
)
|
||||
|
||||
// 数据库链接对象
|
||||
@ -147,8 +148,14 @@ func (db *dbMssql) parseSql(sql string) string {
|
||||
return sql
|
||||
}
|
||||
|
||||
// 返回当前数据库所有的数据表名称
|
||||
// TODO
|
||||
func (bs *dbMssql) Tables() (tables []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值暂无用途(默认为字段数据类型).
|
||||
func (db *dbMssql) getTableFields(table string) (fields map[string]string, err error) {
|
||||
func (db *dbMssql) TableFields(table string) (fields map[string]*TableField, err error) {
|
||||
// 缓存不存在时会查询数据表结构,缓存后不过期,直至程序重启(重新部署)
|
||||
v := db.cache.GetOrSetFunc("mssql_table_fields_"+table, func() interface{} {
|
||||
result := (Result)(nil)
|
||||
@ -162,14 +169,19 @@ func (db *dbMssql) getTableFields(table string) (fields map[string]string, err e
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
fields = make(map[string]string)
|
||||
for _, m := range result {
|
||||
fields[strings.ToLower(m["FIELD"].String())] = strings.ToLower(m["TYPE"].String()) //sqlserver返回的field为大写的需要转为小写的
|
||||
fields = make(map[string]*TableField)
|
||||
for i, m := range result {
|
||||
// SQLServer返回的field为大写的需要转为小写的
|
||||
fields[strings.ToLower(m["FIELD"].String())] = &TableField{
|
||||
Index: i,
|
||||
Name: strings.ToLower(m["FIELD"].String()),
|
||||
Type: strings.ToLower(m["TYPE"].String()),
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}, 0)
|
||||
if err == nil {
|
||||
fields = v.(map[string]string)
|
||||
fields = v.(map[string]*TableField)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -14,10 +14,11 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
)
|
||||
|
||||
// 数据库链接对象
|
||||
@ -120,8 +121,14 @@ func (db *dbOracle) parseSql(sql string) string {
|
||||
return sql
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值暂无用途(默认为字段数据类型).
|
||||
func (db *dbOracle) getTableFields(table string) (fields map[string]string, err error) {
|
||||
// 返回当前数据库所有的数据表名称
|
||||
// TODO
|
||||
func (bs *dbOracle) Tables() (tables []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值为字段数据结构.
|
||||
func (db *dbOracle) TableFields(table string) (fields map[string]*TableField, err error) {
|
||||
// 缓存不存在时会查询数据表结构,缓存后不过期,直至程序重启(重新部署)
|
||||
v := db.cache.GetOrSetFunc("oracle_table_fields_"+table, func() interface{} {
|
||||
result := (Result)(nil)
|
||||
@ -135,14 +142,19 @@ func (db *dbOracle) getTableFields(table string) (fields map[string]string, err
|
||||
return nil
|
||||
}
|
||||
|
||||
fields = make(map[string]string)
|
||||
for _, m := range result {
|
||||
fields[strings.ToLower(m["FIELD"].String())] = strings.ToLower(m["TYPE"].String()) //ORACLE返回的值默认都是大写的,需要转为小写
|
||||
fields = make(map[string]*TableField)
|
||||
for i, m := range result {
|
||||
// ORACLE返回的值默认都是大写的,需要转为小写
|
||||
fields[strings.ToLower(m["FIELD"].String())] = &TableField{
|
||||
Index: i,
|
||||
Name: strings.ToLower(m["FIELD"].String()),
|
||||
Type: strings.ToLower(m["TYPE"].String()),
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}, 0)
|
||||
if err == nil {
|
||||
fields = v.(map[string]string)
|
||||
fields = v.(map[string]*TableField)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -9,8 +9,9 @@ package gdb
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
)
|
||||
|
||||
// PostgreSQL的适配.
|
||||
@ -64,7 +65,14 @@ func (db *dbPgsql) handleSqlBeforeExec(query string) string {
|
||||
return query
|
||||
}
|
||||
|
||||
func (db *dbPgsql) getTableFields(table string) (fields map[string]string, err error) {
|
||||
// 返回当前数据库所有的数据表名称
|
||||
// TODO
|
||||
func (bs *dbPgsql) Tables() (tables []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值为字段数据结构.
|
||||
func (db *dbPgsql) TableFields(table string) (fields map[string]*TableField, err error) {
|
||||
// 缓存不存在时会查询数据表结构,缓存后不过期,直至程序重启(重新部署)
|
||||
table, _ = gregex.ReplaceString("\"", "", table)
|
||||
v := db.cache.GetOrSetFunc("pgsql_table_fields_"+table, func() interface{} {
|
||||
@ -77,14 +85,18 @@ func (db *dbPgsql) getTableFields(table string) (fields map[string]string, err e
|
||||
return nil
|
||||
}
|
||||
|
||||
fields = make(map[string]string)
|
||||
for _, m := range result {
|
||||
fields[m["field"].String()] = m["type"].String()
|
||||
fields = make(map[string]*TableField)
|
||||
for i, m := range result {
|
||||
fields[m["field"].String()] = &TableField{
|
||||
Index: i,
|
||||
Name: m["field"].String(),
|
||||
Type: m["type"].String(),
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}, 0)
|
||||
if err == nil {
|
||||
fields = v.(map[string]string)
|
||||
fields = v.(map[string]*TableField)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@ -40,6 +40,18 @@ func (db *dbSqlite) getChars() (charLeft string, charRight string) {
|
||||
return "`", "`"
|
||||
}
|
||||
|
||||
// 返回当前数据库所有的数据表名称
|
||||
// TODO
|
||||
func (bs *dbSqlite) Tables() (tables []string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值为字段数据结构.
|
||||
// TODO
|
||||
func (db *dbSqlite) TableFields(table string) (fields map[string]*TableField, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// 在执行sql之前对sql进行进一步处理。
|
||||
// @todo 需要增加对Save方法的支持,可使用正则来实现替换,
|
||||
// @todo 将ON DUPLICATE KEY UPDATE触发器修改为两条SQL语句(INSERT OR IGNORE & UPDATE)
|
||||
|
||||
@ -8,23 +8,16 @@ package gdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
|
||||
"github.com/gogf/gf/encoding/gbinary"
|
||||
|
||||
"github.com/gogf/gf/text/gregex"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
)
|
||||
|
||||
//// 同步数据库表结构到内存中
|
||||
//func (bs *dbBase) syncTableStructure() {
|
||||
// bs.tables = make(map[string]map[string]string)
|
||||
// for _, table := range bs.db.getTables() {
|
||||
// bs.tables[table], _ = bs.db.getTableFields(table)
|
||||
// }
|
||||
//}
|
||||
|
||||
// 字段类型转换,将数据库字段类型转换为golang变量类型
|
||||
func (bs *dbBase) convertValue(fieldValue []byte, fieldType string) interface{} {
|
||||
t, _ := gregex.ReplaceString(`\(.+\)`, "", fieldType)
|
||||
@ -86,7 +79,7 @@ func (bs *dbBase) convertValue(fieldValue []byte, fieldType string) interface{}
|
||||
|
||||
// 将map的数据按照fields进行过滤,只保留与表字段同名的数据
|
||||
func (bs *dbBase) filterFields(table string, data map[string]interface{}) map[string]interface{} {
|
||||
if fields, err := bs.db.getTableFields(table); err == nil {
|
||||
if fields, err := bs.db.TableFields(table); err == nil {
|
||||
for k, _ := range data {
|
||||
if _, ok := fields[k]; !ok {
|
||||
delete(data, k)
|
||||
@ -96,8 +89,23 @@ func (bs *dbBase) filterFields(table string, data map[string]interface{}) map[st
|
||||
return data
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值暂无用途(默认为字段数据类型).
|
||||
func (bs *dbBase) getTableFields(table string) (fields map[string]string, err error) {
|
||||
// 返回当前数据库所有的数据表名称
|
||||
func (bs *dbBase) Tables() (tables []string, err error) {
|
||||
result := (Result)(nil)
|
||||
result, err = bs.GetAll(`SHOW TABLES`)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, m := range result {
|
||||
for _, v := range m {
|
||||
tables = append(tables, v.String())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 获得指定表表的数据结构,构造成map哈希表返回,其中键名为表字段名称,键值为字段数据结构.
|
||||
func (bs *dbBase) TableFields(table string) (fields map[string]*TableField, err error) {
|
||||
// 缓存不存在时会查询数据表结构,缓存后不过期,直至程序重启(重新部署)
|
||||
v := bs.cache.GetOrSetFunc("table_fields_"+table, func() interface{} {
|
||||
result := (Result)(nil)
|
||||
@ -105,31 +113,22 @@ func (bs *dbBase) getTableFields(table string) (fields map[string]string, err er
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
fields = make(map[string]string)
|
||||
for _, m := range result {
|
||||
fields[m["Field"].String()] = m["Type"].String()
|
||||
fields = make(map[string]*TableField)
|
||||
for i, m := range result {
|
||||
fields[m["Field"].String()] = &TableField{
|
||||
Index: i,
|
||||
Name: m["Field"].String(),
|
||||
Type: m["Type"].String(),
|
||||
Null: m["Null"].Bool(),
|
||||
Key: m["Key"].String(),
|
||||
Default: m["Default"].Val(),
|
||||
Extra: m["Extra"].String(),
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}, 0)
|
||||
if err == nil {
|
||||
fields = v.(map[string]string)
|
||||
fields = v.(map[string]*TableField)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
// 获取当前数据库所有的表结构
|
||||
func (bs *dbBase) getTables() []string {
|
||||
if result, _ := bs.GetAll(`SHOW TABLES`); result != nil {
|
||||
array := make([]string, len(result))
|
||||
for i, m := range result {
|
||||
for _, v := range m {
|
||||
array[i] = v.String()
|
||||
break
|
||||
}
|
||||
}
|
||||
return array
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/encoding/gbinary"
|
||||
)
|
||||
@ -35,6 +36,7 @@ var (
|
||||
emptyStringMap = map[string]struct{}{
|
||||
"": {},
|
||||
"0": {},
|
||||
"no": {},
|
||||
"off": {},
|
||||
"false": {},
|
||||
}
|
||||
@ -205,7 +207,7 @@ func String(i interface{}) string {
|
||||
}
|
||||
|
||||
// Bool converts <i> to bool.
|
||||
// It returns false if <i> is: false, "", 0, "false", "off", empty slice/map.
|
||||
// It returns false if <i> is: false, "", 0, "false", "off", "no", empty slice/map.
|
||||
func Bool(i interface{}) bool {
|
||||
if i == nil {
|
||||
return false
|
||||
@ -214,12 +216,12 @@ func Bool(i interface{}) bool {
|
||||
case bool:
|
||||
return value
|
||||
case []byte:
|
||||
if _, ok := emptyStringMap[string(value)]; ok {
|
||||
if _, ok := emptyStringMap[strings.ToLower(string(value))]; ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
case string:
|
||||
if _, ok := emptyStringMap[value]; ok {
|
||||
if _, ok := emptyStringMap[strings.ToLower(value)]; ok {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -237,7 +239,7 @@ func Bool(i interface{}) bool {
|
||||
case reflect.Struct:
|
||||
return true
|
||||
default:
|
||||
s := String(i)
|
||||
s := strings.ToLower(String(i))
|
||||
if _, ok := emptyStringMap[s]; ok {
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user