diff --git a/g/database/gdb/gdb.go b/g/database/gdb/gdb.go index fb243c025..f252ab675 100644 --- a/g/database/gdb/gdb.go +++ b/g/database/gdb/gdb.go @@ -11,9 +11,7 @@ import ( "fmt" "errors" "database/sql" - "gitee.com/johng/gf/g/util/gconv" "gitee.com/johng/gf/g/util/grand" - "gitee.com/johng/gf/g/util/gutil" _ "github.com/lib/pq" _ "github.com/go-sql-driver/mysql" ) @@ -36,8 +34,8 @@ type Link interface { Prepare(q string) (*sql.Stmt, error) // 数据库查询 - GetAll(q string, args ...interface{}) (List, error) - GetOne(q string, args ...interface{}) (Map, error) + GetAll(q string, args ...interface{}) (Result, error) + GetOne(q string, args ...interface{}) (Record, error) GetValue(q string, args ...interface{}) (interface{}, error) // Ping @@ -90,11 +88,20 @@ type Db struct { charr string } +// 返回数据表记录值 +type Value string + +// 返回数据表记录Map +type Record map[string]Value + +// 返回数据表记录List +type Result []Record + // 关联数组,绑定一条数据表记录 -type Map map[string]interface{} +type Map map[string]interface{} // 关联数组列表(索引从0开始的数组),绑定多条记录 -type List []Map +type List []Map // MySQL接口对象 var linkMysql = &dbmysql{} @@ -202,40 +209,3 @@ func newDb (masterNode *ConfigNode, slaveNode *ConfigNode) (*Db, error) { }, nil } -// 将Map变量映射到指定的struct对象中,注意参数应当是一个对象的指针 -func (m Map) ToStruct(obj interface{}) error { - return gutil.MapToStruct(m, obj) -} - -// 将结果列表按照指定的字段值做map[string]Map -func (l List) ToStringMap(key string) map[string]Map { - m := make(map[string]Map) - for _, item := range l { - if v, ok := item[key]; ok { - m[gconv.String(v)] = item - } - } - return m -} - -// 将结果列表按照指定的字段值做map[int]Map -func (l List) ToIntMap(key string) map[int]Map { - m := make(map[int]Map) - for _, item := range l { - if v, ok := item[key]; ok { - m[gconv.Int(v)] = item - } - } - return m -} - -// 将结果列表按照指定的字段值做map[uint]Map -func (l List) ToUintMap(key string) map[uint]Map { - m := make(map[uint]Map) - for _, item := range l { - if v, ok := item[key]; ok { - m[gconv.Uint(v)] = item - } - } - return m -} diff --git a/g/database/gdb/gdb_base.go b/g/database/gdb/gdb_base.go index f92e648e8..156dfcd3f 100644 --- a/g/database/gdb/gdb_base.go +++ b/g/database/gdb/gdb_base.go @@ -70,7 +70,7 @@ func (db *Db) formatError(err error, query *string, args ...interface{}) error { // 数据库查询,获取查询结果集,以列表结构返回 -func (db *Db) GetAll(query string, args ...interface{}) (List, error) { +func (db *Db) GetAll(query string, args ...interface{}) (Result, error) { // 执行sql rows, err := db.Query(query, args ...) if err != nil || rows == nil { @@ -84,26 +84,26 @@ func (db *Db) GetAll(query string, args ...interface{}) (List, error) { // 返回结构组装 values := make([]sql.RawBytes, len(columns)) scanArgs := make([]interface{}, len(values)) - var list List + records := make(Result, 0) for i := range values { scanArgs[i] = &values[i] } for rows.Next() { err = rows.Scan(scanArgs...) if err != nil { - return list, err + return records, err } - row := make(Map) + row := make(Record) for i, col := range values { - row[columns[i]] = string(col) + row[columns[i]] = Value(col) } - list = append(list, row) + records = append(records, row) } - return list, nil + return records, nil } // 数据库查询,获取查询结果集,以关联数组结构返回 -func (db *Db) GetOne(query string, args ...interface{}) (Map, error) { +func (db *Db) GetOne(query string, args ...interface{}) (Record, error) { list, err := db.GetAll(query, args ...) if err != nil { return nil, err @@ -136,7 +136,7 @@ func (db *Db) GetCount(query string, args ...interface{}) (int, error) { } // 数据表查询,其中tables可以是多个联表查询语句,这种查询方式较复杂,建议使用链式操作 -func (db *Db) Select(tables, fields string, condition interface{}, groupBy, orderBy string, first, limit int, args ... interface{}) (List, error) { +func (db *Db) Select(tables, fields string, condition interface{}, groupBy, orderBy string, first, limit int, args ... interface{}) (Result, error) { s := fmt.Sprintf("SELECT %s FROM %s ", fields, tables) if condition != nil { s += fmt.Sprintf("WHERE %s ", db.formatCondition(condition)) diff --git a/g/database/gdb/gdb_model.go b/g/database/gdb/gdb_model.go index 9d98e0b18..0551510d1 100644 --- a/g/database/gdb/gdb_model.go +++ b/g/database/gdb/gdb_model.go @@ -250,7 +250,7 @@ func (md *Model) Batch(batch int) *Model { } // 链式操作,select -func (md *Model) Select() (List, error) { +func (md *Model) Select() (Result, error) { if md.tx == nil { return md.db.GetAll(md.getFormattedSql(), md.whereArgs...) } else { @@ -259,12 +259,12 @@ func (md *Model) Select() (List, error) { } // 链式操作,查询所有记录 -func (md *Model) All() (List, error) { +func (md *Model) All() (Result, error) { return md.Select() } // 链式操作,查询单条记录 -func (md *Model) One() (Map, error) { +func (md *Model) One() (Record, error) { list, err := md.All() if err != nil { return nil, err diff --git a/g/database/gdb/gdb_transaction.go b/g/database/gdb/gdb_transaction.go index 06448fd1d..8db23af3d 100644 --- a/g/database/gdb/gdb_transaction.go +++ b/g/database/gdb/gdb_transaction.go @@ -52,7 +52,7 @@ func (tx *Tx) Exec(query string, args ...interface{}) (sql.Result, error) { } // (事务)数据表查询,其中tables可以是多个联表查询语句,这种查询方式较复杂,建议使用链式操作 -func (tx *Tx) Select(tables, fields string, condition interface{}, groupBy, orderBy string, first, limit int, args ... interface{}) (List, error) { +func (tx *Tx) Select(tables, fields string, condition interface{}, groupBy, orderBy string, first, limit int, args ... interface{}) (Result, error) { s := fmt.Sprintf("SELECT %s FROM %s ", fields, tables) if condition != nil { s += fmt.Sprintf("WHERE %s ", tx.db.formatCondition(condition)) @@ -70,7 +70,7 @@ func (tx *Tx) Select(tables, fields string, condition interface{}, groupBy, orde } // (事务)数据库查询,获取查询结果集,以列表结构返回 -func (tx *Tx) GetAll(query string, args ...interface{}) (List, error) { +func (tx *Tx) GetAll(query string, args ...interface{}) (Result, error) { // 执行sql rows, err := tx.Query(query, args ...) if err != nil || rows == nil { @@ -84,26 +84,26 @@ func (tx *Tx) GetAll(query string, args ...interface{}) (List, error) { // 返回结构组装 values := make([]sql.RawBytes, len(columns)) scanArgs := make([]interface{}, len(values)) - var list List + records := make(Result, 0) for i := range values { scanArgs[i] = &values[i] } for rows.Next() { err = rows.Scan(scanArgs...) if err != nil { - return list, err + return records, err } - row := make(Map) + row := make(Record) for i, col := range values { - row[columns[i]] = string(col) + row[columns[i]] = Value(col) } - list = append(list, row) + records = append(records, row) } - return list, nil + return records, nil } // (事务)数据库查询,获取查询结果集,以关联数组结构返回 -func (tx *Tx) GetOne(query string, args ...interface{}) (Map, error) { +func (tx *Tx) GetOne(query string, args ...interface{}) (Record, error) { list, err := tx.GetAll(query, args ...) if err != nil { return nil, err diff --git a/g/database/gdb/gdb_type_record.go b/g/database/gdb/gdb_type_record.go new file mode 100644 index 000000000..fed0c80b5 --- /dev/null +++ b/g/database/gdb/gdb_type_record.go @@ -0,0 +1,20 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gdb + +import ( + "gitee.com/johng/gf/g/util/gutil" +) + +// 将Map变量映射到指定的struct对象中,注意参数应当是一个对象的指针 +func (r Record) ToStruct(obj interface{}) error { + m := make(map[string]interface{}) + for k, v := range r { + m[k] = v + } + return gutil.MapToStruct(m, obj) +} diff --git a/g/database/gdb/gdb_type_result.go b/g/database/gdb/gdb_type_result.go new file mode 100644 index 000000000..37cd04cee --- /dev/null +++ b/g/database/gdb/gdb_type_result.go @@ -0,0 +1,44 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gdb + +import ( + "gitee.com/johng/gf/g/util/gconv" +) + +// 将结果列表按照指定的字段值做map[string]Map +func (r Result) ToStringMap(key string) map[string]Record { + m := make(map[string]Record) + for _, item := range r { + if v, ok := item[key]; ok { + m[gconv.String(v)] = item + } + } + return m +} + +// 将结果列表按照指定的字段值做map[int]Map +func (r Result) ToIntMap(key string) map[int]Record { + m := make(map[int]Record) + for _, item := range r { + if v, ok := item[key]; ok { + m[gconv.Int(v)] = item + } + } + return m +} + +// 将结果列表按照指定的字段值做map[uint]Map +func (r Result) ToUintMap(key string) map[uint]Record { + m := make(map[uint]Record) + for _, item := range r { + if v, ok := item[key]; ok { + m[gconv.Uint(v)] = item + } + } + return m +} diff --git a/g/database/gdb/gdb_type_value.go b/g/database/gdb/gdb_type_value.go new file mode 100644 index 000000000..4e8fe536d --- /dev/null +++ b/g/database/gdb/gdb_type_value.go @@ -0,0 +1,34 @@ +// Copyright 2018 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gdb + +import ( + "time" + "gitee.com/johng/gf/g/util/gconv" +) + +func (v Value) Bytes() []byte { return gconv.Bytes(v) } +func (v Value) String() string { return string(v) } +func (v Value) Bool() bool { return gconv.Bool(v) } + +func (v Value) Int() int { return gconv.Int(v) } +func (v Value) Int8() int8 { return gconv.Int8(v) } +func (v Value) Int16() int16 { return gconv.Int16(v) } +func (v Value) Int32() int32 { return gconv.Int32(v) } +func (v Value) Int64() int64 { return gconv.Int64(v) } + +func (v Value) Uint() uint { return gconv.Uint(v) } +func (v Value) Uint8() uint8 { return gconv.Uint8(v) } +func (v Value) Uint16() uint16 { return gconv.Uint16(v) } +func (v Value) Uint32() uint32 { return gconv.Uint32(v) } +func (v Value) Uint64() uint64 { return gconv.Uint64(v) } + +func (v Value) Float32() float32 { return gconv.Float32(v) } +func (v Value) Float64() float64 { return gconv.Float64(v) } + +func (v Value) Time() time.Time { return gconv.Time(v) } +func (v Value) TimeDuration() time.Duration { return gconv.TimeDuration(v) } \ No newline at end of file diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 1a48832ff..45a06b7fa 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -10,6 +10,7 @@ package gconv import ( "fmt" + "time" "strconv" "gitee.com/johng/gf/g/encoding/gbinary" ) @@ -17,26 +18,47 @@ import ( // 将变量i转换为字符串指定的类型t func Convert(i interface{}, t string) interface{} { switch t { - case "int": return Int(i) - case "int8": return Int8(i) - case "int16": return Int16(i) - case "int32": return Int32(i) - case "int64": return Int64(i) - case "uint": return Uint(i) - case "uint8": return Uint8(i) - case "uint16": return Uint16(i) - case "uint32": return Uint32(i) - case "uint64": return Uint64(i) - case "float32": return Float32(i) - case "float64": return Float64(i) - case "bool": return Bool(i) - case "string": return String(i) - case "[]byte": return Bytes(i) - default: - return i + case "int": return Int(i) + case "int8": return Int8(i) + case "int16": return Int16(i) + case "int32": return Int32(i) + case "int64": return Int64(i) + case "uint": return Uint(i) + case "uint8": return Uint8(i) + case "uint16": return Uint16(i) + case "uint32": return Uint32(i) + case "uint64": return Uint64(i) + case "float32": return Float32(i) + case "float64": return Float64(i) + case "bool": return Bool(i) + case "string": return String(i) + case "[]byte": return Bytes(i) + case "time.Time": return Time(i) + case "time.Duration": return TimeDuration(i) + default: + return i } } +// 将变量i转换为time.Time类型 +func Time(i interface{}) time.Time { + s := String(i) + t := int64(0) + n := int64(0) + if len(s) > 9 { + t = Int64(s[0 : 10]) + if len(s) > 10 { + n = Int64(s[11 : ]) + } + } + return time.Unix(t, n) +} + +// 将变量i转换为time.Time类型 +func TimeDuration(i interface{}) time.Duration { + return time.Duration(Int64(i)) +} + func Bytes(i interface{}) []byte { if i == nil { return nil diff --git a/geg/other/test.go b/geg/other/test.go index 67219643c..f5616886a 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,6 +1,16 @@ package main +import ( + "fmt" + "gitee.com/johng/gf/g/os/gtime" + "gitee.com/johng/gf/g/util/gconv" + "time" + "reflect" +) func main() { + fmt.Println(reflect.TypeOf(gconv.Time(gtime.Second()))) + fmt.Println(time.Unix(gtime.Second(), 0).String()) + } \ No newline at end of file