new version of gdb developing

This commit is contained in:
John
2018-12-14 10:09:45 +08:00
parent c961c22cd7
commit 09e6f10b60
8 changed files with 84 additions and 52 deletions

View File

@ -42,6 +42,8 @@
1. gtcp提供简便的包发送/接收方法(SendPkg/RecvPkg)以解决常见的TCP通信粘包问题并完善文档参考https://www.cnblogs.com/kex1n/p/6502002.html
1. gfile对于文件的读写强行使用了gfpool在某些场景下不合适需要考虑剥离开并为开发者提供单独的指针池文件操作特性
1. 路由增加不区分大小写得匹配方式;
1. str_ireplace: http://php.net/manual/en/function.str-ireplace.php
1. strpos/stripos/strrpos/strripos: http://php.net/manual/en/function.stripos.php

View File

@ -12,12 +12,14 @@ import (
"database/sql"
"gitee.com/johng/gf/g/util/gconv"
_ "gitee.com/johng/gf/third/github.com/go-sql-driver/mysql"
"strings"
)
// 数据库链式操作模型对象
type Model struct {
tx *Tx // 数据库事务对象
db *Db // 数据库操作对象
tablesInit string // 初始化Model时的表名称(可以是多个)
tables string // 数据库操作表
fields string // 操作字段
where string // 操作条件
@ -36,9 +38,10 @@ type Model struct {
// 链式操作,数据表字段,可支持多个表,以半角逗号连接
func (db *Db) Table(tables string) (*Model) {
return &Model{
db: db,
tables: tables,
fields: "*",
db : db,
tablesInit : tables,
tables : tables,
fields : "*",
}
}
@ -50,9 +53,10 @@ func (db *Db) From(tables string) (*Model) {
// (事务)链式操作,数据表字段,可支持多个表,以半角逗号连接
func (tx *Tx) Table(tables string) (*Model) {
return &Model{
db: tx.db,
tx: tx,
tables: tables,
db : tx.db,
tx : tx,
tablesInit : tables,
tables : tables,
}
}
@ -61,6 +65,15 @@ func (tx *Tx) From(tables string) (*Model) {
return tx.Table(tables)
}
// 清空链式操作数据以便改model可以重复使用
func (md *Model) clear() {
if md.tx != nil {
*md = *md.tx.Table(md.tablesInit)
} else {
*md = *md.db.Table(md.tablesInit)
}
}
// 链式操作,左联表
func (md *Model) LeftJoin(joinTable string, on string) (*Model) {
md.tables += fmt.Sprintf(" LEFT JOIN %s ON (%s)", joinTable, on)
@ -87,21 +100,25 @@ func (md *Model) Fields(fields string) (*Model) {
// 链式操作condition支持string & gdb.Map
func (md *Model) Where(where interface{}, args ...interface{}) (*Model) {
md.where = md.db.formatCondition(where)
md.where = md.db.formatCondition(where)
md.whereArgs = append(md.whereArgs, args...)
// 支持 Where("uid", 1)这种格式
if len(args) == 1 && strings.Index(md.where , "?") < 0 {
md.where += "=?"
}
return md
}
// 链式操作添加AND条件到Where中
func (md *Model) And(where interface{}, args ...interface{}) (*Model) {
md.where += " AND " + md.db.formatCondition(where)
md.where += " AND " + md.db.formatCondition(where)
md.whereArgs = append(md.whereArgs, args...)
return md
}
// 链式操作添加OR条件到Where中
func (md *Model) Or(where interface{}, args ...interface{}) (*Model) {
md.where += " OR " + md.db.formatCondition(where)
md.where += " OR " + md.db.formatCondition(where)
md.whereArgs = append(md.whereArgs, args...)
return md
}
@ -153,6 +170,7 @@ func (md *Model) Insert() (result sql.Result, err error) {
if err == nil {
md.checkAndRemoveCache()
}
md.clear()
}()
if md.data == nil {
return nil, errors.New("inserting into table with empty data")
@ -184,6 +202,7 @@ func (md *Model) Replace() (result sql.Result, err error) {
if err == nil {
md.checkAndRemoveCache()
}
md.clear()
}()
if md.data == nil {
return nil, errors.New("replacing into table with empty data")
@ -215,6 +234,7 @@ func (md *Model) Save() (result sql.Result, err error) {
if err == nil {
md.checkAndRemoveCache()
}
md.clear()
}()
if md.data == nil {
return nil, errors.New("replacing into table with empty data")
@ -246,6 +266,7 @@ func (md *Model) Update() (result sql.Result, err error) {
if err == nil {
md.checkAndRemoveCache()
}
md.clear()
}()
if md.data == nil {
return nil, errors.New("updating table with empty data")
@ -263,6 +284,7 @@ func (md *Model) Delete() (result sql.Result, err error) {
if err == nil {
md.checkAndRemoveCache()
}
md.clear()
}()
if md.where == "" {
return nil, errors.New("where is required while deleting")
@ -298,6 +320,7 @@ func (md *Model) Cache(time int, name ... string) *Model {
// 链式操作select
func (md *Model) Select() (Result, error) {
defer md.clear()
return md.getAll(md.getFormattedSql(), md.whereArgs...)
}
@ -342,6 +365,7 @@ func (md *Model) Struct(obj interface{}) error {
// 链式操作查询数量fields可以为空也可以自定义查询字段
// 当给定自定义查询字段时该字段必须为数量结果否则会引起歧义使用如md.Fields("COUNT(id)")
func (md *Model) Count() (int, error) {
defer md.clear()
if md.fields == "" || md.fields == "*" {
md.fields = "COUNT(1)"
} else {
@ -424,11 +448,11 @@ func (md *Model) getFormattedSql() string {
// @author ymrjqyy
// @author 2018-08-15
func (md *Model) Chunk(limit int, callback func(result Result, err error) bool) {
var page = 1
defer md.clear()
page := 1
for {
md.ForPage(page, limit)
sqls := md.getFormattedSql()
data, err := md.getAll(sqls, md.whereArgs...)
data, err := md.getAll(md.getFormattedSql(), md.whereArgs...)
if err != nil {
callback(nil, err)
break

10
g/g.go
View File

@ -10,14 +10,14 @@ package g
import "gitee.com/johng/gf/g/container/gvar"
// 框架动态变量可以用该类型替代interface{}类型
type Var = gvar.Var
type Var = gvar.Var
// 常用map数据结构(使用别名)
type Map = map[string]interface{}
type Map = map[string]interface{}
// 常用list数据结构(使用别名)
type List = []Map
type List = []Map
// 常用slice数据结构(使用别名)
type Slice = []interface{}
type Array = Slice
type Slice = []interface{}
type Array = Slice

View File

@ -25,7 +25,6 @@ func handleProcessSignal() {
syscall.SIGINT,
syscall.SIGQUIT,
syscall.SIGKILL,
syscall.SIGHUP,
syscall.SIGTERM,
syscall.SIGUSR1,
syscall.SIGUSR2,
@ -34,7 +33,7 @@ func handleProcessSignal() {
sig = <- procSignalChan
switch sig {
// 进程终止,停止所有子进程运行
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGTERM:
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGTERM:
shutdownWebServers(sig.String())
return

View File

@ -13,7 +13,7 @@ import (
"strings"
)
// 字符串替换
// 字符串替换(大小写敏感)
func Replace(origin, search, replace string, count...int) string {
n := -1
if len(count) > 0 {
@ -22,7 +22,7 @@ func Replace(origin, search, replace string, count...int) string {
return strings.Replace(origin, search, replace, n)
}
// 使用map进行字符串替换
// 使用map进行字符串替换(大小写敏感)
func ReplaceByMap(origin string, replaces map[string]string) string {
result := origin
for k, v := range replaces {

View File

@ -14,7 +14,12 @@ import (
// 检测键值对参数Map
// rules参数支持 []string / map[string]string 类型,前面一种类型支持返回校验结果顺序(具体格式参考struct tag),后一种不支持;
// rules参数中得 map[string]string 是一个2维的关联数组第一维键名为参数键名第二维为带有错误的校验规则名称值为错误信息。
func CheckMap(params map[string]interface{}, rules interface{}, msgs...CustomMsg) *Error {
func CheckMap(params interface{}, rules interface{}, msgs...CustomMsg) *Error {
// 将参数转换为 map[string]interface{}类型
data := gconv.Map(params)
if data == nil {
return newErrorStr("invalid_params", "invalid params type: convert to map[string]interface{} failed")
}
// 真实校验规则数据结构
checkRules := make(map[string]string)
// 真实自定义错误信息数据结构
@ -74,10 +79,10 @@ func CheckMap(params map[string]interface{}, rules interface{}, msgs...CustomMsg
// 这里的rule变量为多条校验规则不包含名字或者错误信息定义
for key, rule := range checkRules {
value = nil
if v, ok := params[key]; ok {
if v, ok := data[key]; ok {
value = v
}
if e := Check(value, rule, customMsgs[key], params); e != nil {
if e := Check(value, rule, customMsgs[key], data); e != nil {
_, item := e.FirstItem()
// 如果值为nil|""并且不需要require*验证时,其他验证失效
if value == nil || gconv.String(value) == "" {

View File

@ -22,7 +22,7 @@ type Error struct {
type ErrorMap map[string]map[string]string
// 创建一个校验错误对象指针
// 创建一个校验错误对象指针(校验错误)
func newError(rules []string, errors map[string]map[string]string) *Error {
return &Error {
rules : rules,
@ -30,6 +30,18 @@ func newError(rules []string, errors map[string]map[string]string) *Error {
}
}
// 创建一个校验错误对象指针(内部错误)
func newErrorStr(key, err string) *Error {
return &Error {
rules : nil,
errors : map[string]map[string]string{
"__gvalid__" : {
key: err,
},
},
}
}
// 获得规则与错误信息的map; 当校验结果为多条数据校验时返回第一条错误map(此时类似FirstItem)
func (e *Error) Map() map[string]string {
_, m := e.FirstItem()

View File

@ -1,35 +1,25 @@
package main
import (
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/util/gvalid"
)
import "fmt"
type User struct {
Uid int `gvalid:"uid @integer|min:1"`
Name string `gvalid:"name @required|length:6,30#请输入用户名称|用户名称长度非法"`
Pass1 string `gvalid:"password1@required|password3"`
Pass2 string `gvalid:"password2@required|password3|same:password1#||两次密码不一致,请重新输入"`
Uid int
}
func New() *User {
return &User{
100,
}
}
func (user *User) Clear() {
user = New()
}
func main() {
user := &User{
Name : "john",
Pass1: "Abc123!@#",
Pass2: "123",
}
// 使用结构体定义的校验规则和错误提示进行校验
g.Dump(gvalid.CheckStruct(user, nil).Maps())
// 自定义校验规则和错误提示,对定义的特定校验规则和错误提示进行覆盖
rules := map[string]string {
"Uid" : "required",
}
msgs := map[string]interface{} {
"Pass2" : map[string]string {
"password3" : "名称不能为空",
},
}
g.Dump(gvalid.CheckStruct(user, rules, msgs).Maps())
user := New()
user.Uid = 10000
fmt.Println(user)
user.Clear()
fmt.Println(user)
}