add GetVar function for package genv; add DryRun feature for package gdb

This commit is contained in:
John
2020-04-02 20:52:37 +08:00
parent be2d4b080e
commit 7bcc596308
11 changed files with 120 additions and 23 deletions

View File

@ -89,6 +89,8 @@ type DB interface {
SetSchema(schema string)
GetSchema() string
GetPrefix() string
SetDryRun(dryrun bool)
GetDryRun() bool
SetLogger(logger *glog.Logger)
GetLogger() *glog.Logger
SetMaxIdleConnCount(n int)
@ -124,6 +126,7 @@ type Core struct {
debug *gtype.Bool // Enable debug mode for the database.
cache *gcache.Cache // Cache manager.
schema *gtype.String // Custom schema for this object.
dryrun *gtype.Bool // Dry run.
prefix string // Table prefix.
logger *glog.Logger // Logger.
maxIdleConnCount int // Max idle connection count.
@ -234,6 +237,7 @@ func New(name ...string) (db DB, err error) {
debug: gtype.NewBool(),
cache: gcache.New(),
schema: gtype.NewString(),
dryrun: gtype.NewBool(),
logger: glog.New(),
prefix: node.Prefix,
maxIdleConnCount: gDEFAULT_CONN_MAX_IDLE_COUNT,
@ -401,5 +405,8 @@ func (c *Core) getSqlDb(master bool, schema ...string) (sqlDb *sql.DB, err error
if node.Debug {
c.DB.SetDebug(node.Debug)
}
if node.Debug {
c.DB.SetDryRun(node.DryRun)
}
return
}

View File

@ -99,7 +99,11 @@ func (c *Core) DoExec(link Link, sql string, args ...interface{}) (result sql.Re
sql, args = c.DB.HandleSqlBeforeCommit(link, sql, args)
if c.DB.GetDebug() {
mTime1 := gtime.TimestampMilli()
result, err = link.Exec(sql, args...)
if !c.DB.GetDryRun() {
result, err = link.Exec(sql, args...)
} else {
result = new(SqlResult)
}
mTime2 := gtime.TimestampMilli()
s := &Sql{
Sql: sql,
@ -111,7 +115,11 @@ func (c *Core) DoExec(link Link, sql string, args ...interface{}) (result sql.Re
}
c.writeSqlToLogger(s)
} else {
result, err = link.Exec(sql, args...)
if !c.DB.GetDryRun() {
result, err = link.Exec(sql, args...)
} else {
result = new(SqlResult)
}
}
return result, formatError(err, sql, args...)
}

View File

@ -36,6 +36,7 @@ type ConfigNode struct {
Role string // (Optional, "master" in default) Node role, used for master-slave mode: master, slave.
Debug bool // (Optional) Debug mode enables debug information logging and output.
Prefix string // (Optional) Table prefix.
DryRun bool // (Optional) Dry run, which does SELECT but no INSERT/UPDATE/DELETE statements.
Weight int // (Optional) Weight for load balance calculating, it's useless if there's just one node.
Charset string // (Optional, "utf8mb4" in default) Custom charset when operating on database.
LinkInfo string // (Optional) Custom link information, when it is used, configuration Host/Port/User/Pass/Name are ignored.
@ -142,24 +143,19 @@ func (c *Core) SetMaxConnLifetime(d time.Duration) {
// String returns the node as string.
func (node *ConfigNode) String() string {
if node.LinkInfo != "" {
return node.LinkInfo
}
return fmt.Sprintf(
`%s@%s:%s,%s,%s,%s,%s,%v,%d-%d-%d`,
`%s@%s:%s,%s,%s,%s,%s,%v,%d-%d-%d#%s`,
node.User, node.Host, node.Port,
node.Name, node.Type, node.Role, node.Charset, node.Debug,
node.MaxIdleConnCount,
node.MaxOpenConnCount,
node.MaxConnLifetime,
node.LinkInfo,
)
}
// SetDebug enables/disables the debug mode.
func (c *Core) SetDebug(debug bool) {
if c.debug.Val() == debug {
return
}
c.debug.Set(debug)
}
@ -178,6 +174,16 @@ func (c *Core) GetPrefix() string {
return c.prefix
}
// SetDryRun enables/disables the DryRun feature.
func (c *Core) SetDryRun(dryrun bool) {
c.dryrun.Set(dryrun)
}
// GetDryRun returns the DryRun value.
func (c *Core) GetDryRun() bool {
return c.dryrun.Val()
}
// SetSchema changes the schema for this database connection object.
// Importantly note that when schema configuration changed for the database,
// it affects all operations on the database object in the future.

View File

@ -10,6 +10,7 @@ import (
"database/sql"
"fmt"
"github.com/gogf/gf/internal/intlog"
"github.com/gogf/gf/text/gregex"
"github.com/gogf/gf/text/gstr"
_ "github.com/go-sql-driver/mysql"
@ -33,6 +34,10 @@ func (d *DriverMysql) Open(config *ConfigNode) (*sql.DB, error) {
var source string
if config.LinkInfo != "" {
source = config.LinkInfo
// Custom changing the schema in runtime.
if config.Name != "" {
source, _ = gregex.ReplaceString(`/([\w\.\-]+)+`, "/"+config.Name, source)
}
} else {
source = fmt.Sprintf(
"%s:%s@tcp(%s:%s)/%s?charset=%s&multiStatements=true&parseTime=true&loc=Local",

View File

@ -38,10 +38,16 @@ func (r *SqlResult) RowsAffected() (int64, error) {
if r.affected > 0 {
return r.affected, nil
}
if r.result == nil {
return 0, nil
}
return r.result.RowsAffected()
}
// see sql.Result.LastInsertId
func (r *SqlResult) LastInsertId() (int64, error) {
if r.result == nil {
return 0, nil
}
return r.result.LastInsertId()
}

View File

@ -9,11 +9,33 @@ package gdb
import (
"database/sql"
"fmt"
"math"
"reflect"
"github.com/gogf/gf/encoding/gparser"
)
// Chunk splits an Result into multiple Results,
// the size of each array is determined by <size>.
// The last chunk may contain less than size elements.
func (r Result) Chunk(size int) []Result {
if size < 1 {
return nil
}
length := len(r)
chunks := int(math.Ceil(float64(length) / float64(size)))
var n []Result
for i, end := 0, 0; chunks > 0; chunks-- {
end = (i + 1) * size
if end > length {
end = length
}
n = append(n, r[i*size:end])
i++
}
return n
}
// Json converts <r> to JSON format content.
func (r Result) Json() string {
content, _ := gparser.VarToJson(r.List())

View File

@ -2123,3 +2123,38 @@ func Test_Model_OmitEmpty_Time(t *testing.T) {
t.Assert(n, 1)
})
}
func Test_Result_Chunk(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
r, err := db.Table(table).Order("id asc").All()
t.Assert(err, nil)
chunks := r.Chunk(3)
t.Assert(len(chunks), 4)
t.Assert(chunks[0][0]["id"].Int(), 1)
t.Assert(chunks[1][0]["id"].Int(), 4)
t.Assert(chunks[2][0]["id"].Int(), 7)
t.Assert(chunks[3][0]["id"].Int(), 10)
})
}
func Test_Model_DryRun(t *testing.T) {
table := createInitTable()
defer dropTable(table)
db.SetDryRun(true)
defer db.SetDryRun(false)
gtest.C(t, func(t *gtest.T) {
one, err := db.Table(table).FindOne(1)
t.Assert(err, nil)
t.Assert(one["id"], 1)
})
gtest.C(t, func(t *gtest.T) {
r, err := db.Table(table).Data("passport", "port_1").WherePri(1).Update()
t.Assert(err, nil)
n, err := r.RowsAffected()
t.Assert(err, nil)
t.Assert(n, 0)
})
}