improve gutil.Dump, improve sqlite file searching when opening db file

This commit is contained in:
John
2020-03-19 13:38:42 +08:00
parent 849e7370d1
commit 36401a063d
9 changed files with 126 additions and 259 deletions

View File

@ -8,51 +8,52 @@ package garray_test
import (
"fmt"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/container/garray"
)
func Example_basic() {
// 创建普通的数组
func Example_Basic() {
// A normal array.
a := garray.New()
// 添加数据项
// Adding items.
for i := 0; i < 10; i++ {
a.Append(i)
}
// 获取当前数组长度
// Print the array length.
fmt.Println(a.Len())
// 获取当前数据项列表
// Print the array items.
fmt.Println(a.Slice())
// 获取指定索引项
// Retrieve item by index.
fmt.Println(a.Get(6))
// 查找指定数据项是否存在
// Check item existence.
fmt.Println(a.Contains(6))
fmt.Println(a.Contains(100))
// 在指定索引前插入数据项
// Insert item before specified index.
a.InsertAfter(9, 11)
// 在指定索引后插入数据项
// Insert item after specified index.
a.InsertBefore(10, 10)
fmt.Println(a.Slice())
// 修改指定索引的数据项
// Modify item by index.
a.Set(0, 100)
fmt.Println(a.Slice())
// 搜索数据项,返回搜索到的索引位置
// Search item and return its index.
fmt.Println(a.Search(5))
// 删除指定索引的数据项
// Remove item by index.
a.Remove(0)
fmt.Println(a.Slice())
// 清空数组
// Empty the array, removes all items of it.
fmt.Println(a.Slice())
a.Clear()
fmt.Println(a.Slice())
@ -71,15 +72,23 @@ func Example_basic() {
// []
}
func Example_rand() {
func Example_Rand() {
array := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9})
// 随机返回两个数据项(不删除)
// Randomly retrieve and return 2 items from the array.
// It does not delete the items from array.
fmt.Println(array.Rands(2))
// Randomly pick and return one item from the array.
// It deletes the picked up item from array.
fmt.Println(array.PopRand())
}
func Example_pop() {
func Example_PopItem() {
array := garray.NewFrom([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9})
// Any Pop* functions pick, delete and return the item from array.
fmt.Println(array.PopLeft())
fmt.Println(array.PopLefts(2))
fmt.Println(array.PopRight())
@ -92,7 +101,7 @@ func Example_pop() {
// [7 8]
}
func Example_merge() {
func Example_MergeArray() {
array1 := garray.NewFrom([]interface{}{1, 2})
array2 := garray.NewFrom([]interface{}{3, 4})
slice1 := []interface{}{5, 6}
@ -110,3 +119,14 @@ func Example_merge() {
// [1 2]
// [1 2 1 2 3 4 5 6 7 8 9 0]
}
func Example_Filter() {
array1 := garray.NewFrom(g.Slice{0, 1, 2, nil, "", g.Slice{}, "john"})
array2 := garray.NewFrom(g.Slice{0, 1, 2, nil, "", g.Slice{}, "john"})
fmt.Printf("%#v\n", array1.FilterNil().Slice())
fmt.Printf("%#v\n", array2.FilterEmpty().Slice())
// Output:
// []interface {}{0, 1, 2, "", []interface {}{}, "john"}
// []interface {}{1, 2, "john"}
}

View File

@ -11,6 +11,7 @@ import (
"database/sql"
"errors"
"fmt"
"github.com/gogf/gf/internal/intlog"
"time"
"github.com/gogf/gf/os/glog"
@ -370,6 +371,7 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error
v := c.cache.GetOrSetFuncLock(node.String(), func() interface{} {
sqlDb, err = c.DB.Open(node)
if err != nil {
intlog.Printf("DB open failed: %v, %+v", err, node)
return nil
}
if c.maxIdleConnCount > 0 {

View File

@ -14,6 +14,7 @@ import (
"database/sql"
"fmt"
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/os/gfile"
"github.com/gogf/gf/text/gstr"
"strings"
)
@ -34,11 +35,16 @@ func (d *DriverSqlite) New(core *Core, node *ConfigNode) (DB, error) {
// Open creates and returns a underlying sql.DB object for sqlite.
func (d *DriverSqlite) Open(config *ConfigNode) (*sql.DB, error) {
var source string
var err error
if config.LinkInfo != "" {
source = config.LinkInfo
} else {
source = config.Name
}
source, err = gfile.Search(source)
if err != nil {
return nil, err
}
intlog.Printf("Open: %s", source)
if db, err := sql.Open("sqlite3", source); err == nil {
return db, nil

View File

@ -24,8 +24,8 @@ import (
// Get send GET request and returns the response object.
// Note that the response object MUST be closed if it'll be never used.
func (c *Client) Get(url string) (*ClientResponse, error) {
return c.DoRequest("GET", url)
func (c *Client) Get(url string, data ...interface{}) (*ClientResponse, error) {
return c.DoRequest("GET", url, data...)
}
// Put send PUT request and returns the response object.

View File

@ -12,14 +12,14 @@ import (
"github.com/gogf/gf/util/gconv"
)
// GetRequest retrieves and returns the parameter named <key> passed from client as interface{},
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequest retrieves and returns the parameter named <key> passed from client and
// custom params as interface{}, no matter what HTTP method the client is using. The
// parameter <def> specifies the default value if the <key> does not exist.
//
// GetRequest is one of the most commonly used functions for retrieving parameters.
//
// Note that if there're multiple parameters with the same name, the parameters are retrieved and overwrote
// in order of priority: router < query < body < form < custom.
// Note that if there're multiple parameters with the same name, the parameters are
// retrieved and overwrote in order of priority: router < query < body < form < custom.
func (r *Request) GetRequest(key string, def ...interface{}) interface{} {
value := r.GetParam(key)
if value == nil {
@ -46,127 +46,127 @@ func (r *Request) GetRequest(key string, def ...interface{}) interface{} {
return value
}
// GetRequestVar retrieves and returns the parameter named <key> passed from client as *gvar.Var,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestVar retrieves and returns the parameter named <key> passed from client and
// custom params as *gvar.Var, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestVar(key string, def ...interface{}) *gvar.Var {
return gvar.New(r.GetRequest(key, def...))
}
// GetRequestString retrieves and returns the parameter named <key> passed from client as string,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestString retrieves and returns the parameter named <key> passed from client and
// custom params as string, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestString(key string, def ...interface{}) string {
return r.GetRequestVar(key, def...).String()
}
// GetRequestBool retrieves and returns the parameter named <key> passed from client as bool,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestBool retrieves and returns the parameter named <key> passed from client and
// custom params as bool, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestBool(key string, def ...interface{}) bool {
return r.GetRequestVar(key, def...).Bool()
}
// GetRequestInt retrieves and returns the parameter named <key> passed from client as int,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestInt retrieves and returns the parameter named <key> passed from client and
// custom params as int, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInt(key string, def ...interface{}) int {
return r.GetRequestVar(key, def...).Int()
}
// GetRequestInt32 retrieves and returns the parameter named <key> passed from client as int32,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestInt32 retrieves and returns the parameter named <key> passed from client and
// custom params as int32, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInt32(key string, def ...interface{}) int32 {
return r.GetRequestVar(key, def...).Int32()
}
// GetRequestInt64 retrieves and returns the parameter named <key> passed from client as int64,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestInt64 retrieves and returns the parameter named <key> passed from client and
// custom params as int64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInt64(key string, def ...interface{}) int64 {
return r.GetRequestVar(key, def...).Int64()
}
// GetRequestInts retrieves and returns the parameter named <key> passed from client as []int,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestInts retrieves and returns the parameter named <key> passed from client and
// custom params as []int, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInts(key string, def ...interface{}) []int {
return r.GetRequestVar(key, def...).Ints()
}
// GetRequestUint retrieves and returns the parameter named <key> passed from client as uint,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestUint retrieves and returns the parameter named <key> passed from client and
// custom params as uint, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestUint(key string, def ...interface{}) uint {
return r.GetRequestVar(key, def...).Uint()
}
// GetRequestUint32 retrieves and returns the parameter named <key> passed from client as uint32,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestUint32 retrieves and returns the parameter named <key> passed from client and
// custom params as uint32, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestUint32(key string, def ...interface{}) uint32 {
return r.GetRequestVar(key, def...).Uint32()
}
// GetRequestUint64 retrieves and returns the parameter named <key> passed from client as uint64,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestUint64 retrieves and returns the parameter named <key> passed from client and
// custom params as uint64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestUint64(key string, def ...interface{}) uint64 {
return r.GetRequestVar(key, def...).Uint64()
}
// GetRequestFloat32 retrieves and returns the parameter named <key> passed from client as float32,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestFloat32 retrieves and returns the parameter named <key> passed from client and
// custom params as float32, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestFloat32(key string, def ...interface{}) float32 {
return r.GetRequestVar(key, def...).Float32()
}
// GetRequestFloat64 retrieves and returns the parameter named <key> passed from client as float64,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestFloat64 retrieves and returns the parameter named <key> passed from client and
// custom params as float64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestFloat64(key string, def ...interface{}) float64 {
return r.GetRequestVar(key, def...).Float64()
}
// GetRequestFloats retrieves and returns the parameter named <key> passed from client as []float64,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestFloats retrieves and returns the parameter named <key> passed from client and
// custom params as []float64, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestFloats(key string, def ...interface{}) []float64 {
return r.GetRequestVar(key, def...).Floats()
}
// GetRequestArray retrieves and returns the parameter named <key> passed from client as []string,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestArray retrieves and returns the parameter named <key> passed from client and
// custom params as []string, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestArray(key string, def ...interface{}) []string {
return r.GetRequestVar(key, def...).Strings()
}
// GetRequestStrings retrieves and returns the parameter named <key> passed from client as []string,
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestStrings retrieves and returns the parameter named <key> passed from client and
// custom params as []string, no matter what HTTP method the client is using. The parameter
// <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestStrings(key string, def ...interface{}) []string {
return r.GetRequestVar(key, def...).Strings()
}
// GetRequestInterfaces retrieves and returns the parameter named <key> passed from client as []interface{},
// no matter what HTTP method the client is using. The parameter <def> specifies the default value
// if the <key> does not exist.
// GetRequestInterfaces retrieves and returns the parameter named <key> passed from client
// and custom params as []interface{}, no matter what HTTP method the client is using. The
// parameter <def> specifies the default value if the <key> does not exist.
func (r *Request) GetRequestInterfaces(key string, def ...interface{}) []interface{} {
return r.GetRequestVar(key, def...).Interfaces()
}
// GetRequestMap retrieves and returns all parameters passed from client as map,
// no matter what HTTP method the client is using. The parameter <kvMap> specifies the keys
// retrieving from client parameters, the associated values are the default values if the client
// does not pass the according keys.
// GetRequestMap retrieves and returns all parameters passed from client and custom params
// as map, no matter what HTTP method the client is using. The parameter <kvMap> specifies
// the keys retrieving from client parameters, the associated values are the default values
// if the client does not pass the according keys.
//
// GetRequestMap is one of the most commonly used functions for retrieving parameters.
//
// Note that if there're multiple parameters with the same name, the parameters are retrieved and overwrote
// in order of priority: router < query < body < form < custom.
// Note that if there're multiple parameters with the same name, the parameters are retrieved
// and overwrote in order of priority: router < query < body < form < custom.
func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]interface{} {
r.parseQuery()
r.parseForm()
@ -231,10 +231,10 @@ func (r *Request) GetRequestMap(kvMap ...map[string]interface{}) map[string]inte
return m
}
// GetRequestMapStrStr retrieves and returns all parameters passed from client as map[string]string,
// no matter what HTTP method the client is using. The parameter <kvMap> specifies the keys
// retrieving from client parameters, the associated values are the default values if the client
// does not pass.
// GetRequestMapStrStr retrieves and returns all parameters passed from client and custom
// params as map[string]string, no matter what HTTP method the client is using. The parameter
// <kvMap> specifies the keys retrieving from client parameters, the associated values are the
// default values if the client does not pass.
func (r *Request) GetRequestMapStrStr(kvMap ...map[string]interface{}) map[string]string {
requestMap := r.GetRequestMap(kvMap...)
if len(requestMap) > 0 {
@ -247,10 +247,10 @@ func (r *Request) GetRequestMapStrStr(kvMap ...map[string]interface{}) map[strin
return nil
}
// GetRequestMapStrVar retrieves and returns all parameters passed from client as map[string]*gvar.Var,
// no matter what HTTP method the client is using. The parameter <kvMap> specifies the keys
// retrieving from client parameters, the associated values are the default values if the client
// does not pass.
// GetRequestMapStrVar retrieves and returns all parameters passed from client and custom
// params as map[string]*gvar.Var, no matter what HTTP method the client is using. The parameter
// <kvMap> specifies the keys retrieving from client parameters, the associated values are the
// default values if the client does not pass.
func (r *Request) GetRequestMapStrVar(kvMap ...map[string]interface{}) map[string]*gvar.Var {
requestMap := r.GetRequestMap(kvMap...)
if len(requestMap) > 0 {
@ -263,8 +263,9 @@ func (r *Request) GetRequestMapStrVar(kvMap ...map[string]interface{}) map[strin
return nil
}
// GetRequestStruct retrieves all parameters passed from client no matter what HTTP method the client is using,
// and converts them to given struct object. Note that the parameter <pointer> is a pointer to the struct object.
// GetRequestStruct retrieves all parameters passed from client and custom params no matter
// what HTTP method the client is using, and converts them to given struct object. Note that
// the parameter <pointer> is a pointer to the struct object.
// The optional parameter <mapping> is used to specify the key to attribute mapping.
func (r *Request) GetRequestStruct(pointer interface{}, mapping ...map[string]string) error {
tagMap := structs.TagMapName(pointer, paramTagPriority, true)

View File

@ -59,7 +59,7 @@ func Benchmark_GMutex_TryLock(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if gmu.TryLock() {
defer gmu.Unlock()
gmu.Unlock()
}
}
})
@ -77,7 +77,9 @@ func Benchmark_GMutex_RLockRUnlock(b *testing.B) {
func Benchmark_GMutex_TryRLock(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
gmu.TryRLock()
if gmu.TryRLock() {
gmu.RUnlock()
}
}
})
}

View File

@ -122,7 +122,6 @@ func Convert(i interface{}, t string, params ...interface{}) interface{} {
case "Duration", "time.Duration":
return Duration(i)
default:
return i
}
}

View File

@ -8,44 +8,9 @@
package gutil
import (
"bytes"
"encoding/json"
"fmt"
"os"
"github.com/gogf/gf/internal/empty"
"github.com/gogf/gf/util/gconv"
)
// Dump prints variables <i...> to stdout with more manually readable.
func Dump(i ...interface{}) {
s := Export(i...)
if s != "" {
fmt.Println(s)
}
}
// Export returns variables <i...> as a string with more manually readable.
func Export(i ...interface{}) string {
buffer := bytes.NewBuffer(nil)
for _, v := range i {
if b, ok := v.([]byte); ok {
buffer.Write(b)
} else {
if m := gconv.Map(v); m != nil && len(m) > 0 {
v = m
}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
encoder.SetIndent("", "\t")
if err := encoder.Encode(v); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
}
}
return buffer.String()
}
// Throw throws out an exception, which can be caught be TryCatch or recover.
func Throw(exception interface{}) {
panic(exception)

View File

@ -4,19 +4,15 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// Package gutil provides utility functions.
package gutil
import (
"bytes"
"encoding/json"
"fmt"
"github.com/gogf/gf/util/gconv"
"os"
"reflect"
"strings"
"github.com/gogf/gf/internal/empty"
"github.com/gogf/gf/util/gconv"
)
// Dump prints variables <i...> to stdout with more manually readable.
@ -34,111 +30,17 @@ func Export(i ...interface{}) string {
if b, ok := v.([]byte); ok {
buffer.Write(b)
} else {
rv := reflect.ValueOf(value)
rv := reflect.ValueOf(v)
kind := rv.Kind()
// If it is a pointer, we should find its real data type.
if kind == reflect.Ptr {
rv = rv.Elem()
kind = rv.Kind()
}
switch kind {
// If <value> is type of array, it converts the value of even number index as its key and
// the value of odd number index as its corresponding value.
// Eg:
// []string{"k1","v1","k2","v2"} => map[string]interface{}{"k1":"v1", "k2":"v2"}
// []string{"k1","v1","k2"} => map[string]interface{}{"k1":"v1", "k2":nil}
case reflect.Slice, reflect.Array:
length := rv.Len()
for i := 0; i < length; i += 2 {
if i+1 < length {
m[String(rv.Index(i).Interface())] = rv.Index(i + 1).Interface()
} else {
m[String(rv.Index(i).Interface())] = nil
}
}
case reflect.Map:
ks := rv.MapKeys()
for _, k := range ks {
m[String(k.Interface())] = rv.MapIndex(k).Interface()
}
case reflect.Struct:
// Map converting interface check.
if v, ok := value.(apiMapStrAny); ok {
return v.MapStrAny()
}
rt := rv.Type()
name := ""
tagArray := structTagPriority
switch len(tags) {
case 0:
// No need handle.
case 1:
tagArray = append(strings.Split(tags[0], ","), structTagPriority...)
default:
tagArray = append(tags, structTagPriority...)
}
var rtField reflect.StructField
var rvField reflect.Value
var rvKind reflect.Kind
for i := 0; i < rv.NumField(); i++ {
rtField = rt.Field(i)
rvField = rv.Field(i)
// Only convert the public attributes.
fieldName := rtField.Name
if !utils.IsLetterUpper(fieldName[0]) {
continue
}
name = ""
fieldTag := rtField.Tag
for _, tag := range tagArray {
if name = fieldTag.Get(tag); name != "" {
break
}
}
if name == "" {
name = strings.TrimSpace(fieldName)
} else {
// Support json tag feature: -, omitempty
name = strings.TrimSpace(name)
if name == "-" {
continue
}
array := strings.Split(name, ",")
if len(array) > 1 {
switch strings.TrimSpace(array[1]) {
case "omitempty":
if empty.IsEmpty(rvField.Interface()) {
continue
} else {
name = strings.TrimSpace(array[0])
}
default:
name = strings.TrimSpace(array[0])
}
}
}
if recursive {
rvKind = rvField.Kind()
if rvKind == reflect.Ptr {
rvField = rvField.Elem()
rvKind = rvField.Kind()
}
if rvKind == reflect.Struct {
for k, v := range doMapConvert(rvField.Interface(), recursive, tags...) {
m[k] = v
}
} else {
m[name] = rvField.Interface()
}
} else {
m[name] = rvField.Interface()
}
}
default:
return nil
}
if m := gconv.Map(v); m != nil && len(m) > 0 {
v = m
v = gconv.Interfaces(v)
case reflect.Map, reflect.Struct:
v = gconv.Map(v)
}
encoder := json.NewEncoder(buffer)
encoder.SetEscapeHTML(false)
@ -150,33 +52,3 @@ func Export(i ...interface{}) string {
}
return buffer.String()
}
// Throw throws out an exception, which can be caught be TryCatch or recover.
func Throw(exception interface{}) {
panic(exception)
}
// TryCatch implements try...catch... logistics.
func TryCatch(try func(), catch ...func(exception interface{})) {
if len(catch) > 0 {
// If <catch> is given, it's used to handle the exception.
defer func() {
if e := recover(); e != nil {
catch[0](e)
}
}()
} else {
// If no <catch> function passed, it filters the exception.
defer func() {
recover()
}()
}
try()
}
// IsEmpty checks given <value> empty or not.
// It returns false if <value> is: integer(0), bool(false), slice/map(len=0), nil;
// or else returns true.
func IsEmpty(value interface{}) bool {
return empty.IsEmpty(value)
}