From c2d44e5947b1d775fb5aeed620ae8261d2f599b3 Mon Sep 17 00:00:00 2001 From: Shiny Date: Tue, 17 Dec 2024 22:47:16 +0800 Subject: [PATCH] =?UTF-8?q?gin=E4=B8=8D=E4=BE=9D=E8=B5=96=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 40 ++-- lightCore/Config.go | 2 - lightCore/Db.go | 21 -- lightCore/GromAdapter.go | 11 - lightCore/LightCore.go | 8 +- lightCore/Start.go | 4 - pkg/mySql/Create.go | 9 + pkg/mySql/Delete.go | 55 +++++ pkg/mySql/Facade.go | 50 +++++ pkg/mySql/Insert.go | 83 ++++++++ pkg/mySql/InsertColumn.go | 10 + pkg/mySql/Join.go | 11 + pkg/mySql/PageStruct.go | 8 + pkg/mySql/Query.go | 420 ++++++++++++++++++++++++++++++++++++++ pkg/mySql/QueryJoin.go | 53 +++++ pkg/mySql/QueryManager.go | 91 +++++++++ pkg/mySql/QueryOrderBy.go | 42 ++++ pkg/mySql/QueryWhere.go | 110 ++++++++++ pkg/mySql/Reflect.go | 24 +++ pkg/mySql/SqlMapper.go | 78 +++++++ pkg/mySql/StringSplit.go | 56 +++++ pkg/mySql/Update.go | 127 ++++++++++++ pkg/mySql/Where.go | 115 +++++++++++ test/start_test.go | 9 + 24 files changed, 1377 insertions(+), 60 deletions(-) delete mode 100644 lightCore/Db.go delete mode 100644 lightCore/GromAdapter.go create mode 100644 pkg/mySql/Create.go create mode 100644 pkg/mySql/Delete.go create mode 100644 pkg/mySql/Facade.go create mode 100644 pkg/mySql/Insert.go create mode 100644 pkg/mySql/InsertColumn.go create mode 100644 pkg/mySql/Join.go create mode 100644 pkg/mySql/PageStruct.go create mode 100644 pkg/mySql/Query.go create mode 100644 pkg/mySql/QueryJoin.go create mode 100644 pkg/mySql/QueryManager.go create mode 100644 pkg/mySql/QueryOrderBy.go create mode 100644 pkg/mySql/QueryWhere.go create mode 100644 pkg/mySql/Reflect.go create mode 100644 pkg/mySql/SqlMapper.go create mode 100644 pkg/mySql/StringSplit.go create mode 100644 pkg/mySql/Update.go create mode 100644 pkg/mySql/Where.go diff --git a/go.mod b/go.mod index 14362e0..2951b34 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module code.zhecent.com/gopkg/light-core go 1.23.1 require ( + github.com/Masterminds/squirrel v1.5.4 github.com/aliyun/alibaba-cloud-sdk-go v1.63.68 github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/gin-gonic/gin v1.10.0 @@ -19,14 +20,15 @@ require ( ) require ( - github.com/bytedance/sonic v1.11.6 // indirect - github.com/bytedance/sonic/loader v0.1.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/bytedance/sonic v1.12.2 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-pay/crypto v0.0.1 // indirect github.com/go-pay/errgroup v0.0.2 // indirect @@ -35,16 +37,18 @@ require ( github.com/go-pay/xtime v0.0.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.20.0 // indirect - github.com/go-sql-driver/mysql v1.7.0 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/go-playground/validator/v10 v10.22.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect + github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -52,24 +56,24 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect - github.com/pelletier/go-toml/v2 v2.2.2 // indirect - github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/sagikazarmark/locafero v0.6.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect - golang.org/x/arch v0.8.0 // indirect - golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect - golang.org/x/net v0.25.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/arch v0.9.0 // indirect + golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect + golang.org/x/net v0.28.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/time v0.8.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/lightCore/Config.go b/lightCore/Config.go index eeebf02..ef916b2 100644 --- a/lightCore/Config.go +++ b/lightCore/Config.go @@ -1,7 +1,5 @@ package lightCore -var ConfigValue = &Config{} - type Config struct { App AppConfigModel `mapstructure:"app" yaml:"app"` Server ServerConfigModel `mapstructure:"server" yaml:"server"` diff --git a/lightCore/Db.go b/lightCore/Db.go deleted file mode 100644 index b03d4e3..0000000 --- a/lightCore/Db.go +++ /dev/null @@ -1,21 +0,0 @@ -package lightCore - -import ( - "code.zhecent.com/gopkg/light-core/pkg/myGorm" - "gorm.io/gorm" -) - -var DBEngine *gorm.DB - -func InitDB() { - orm := myGorm.NewSimpleORM( - ConfigValue.Database.User, - ConfigValue.Database.Password, - ConfigValue.Database.Host, - ConfigValue.Database.Name, - ConfigValue.Database.Charset, - ConfigValue.Server.RunMode, - ) - orm.SetLoggerLevel(ConfigValue.Database.LogLevel) - DBEngine = orm.ConnectMysql() -} diff --git a/lightCore/GromAdapter.go b/lightCore/GromAdapter.go deleted file mode 100644 index 7f2f6e4..0000000 --- a/lightCore/GromAdapter.go +++ /dev/null @@ -1,11 +0,0 @@ -package lightCore - -import "gorm.io/gorm" - -type GormAdapter struct { - *gorm.DB -} - -func NewGormAdapter(db *gorm.DB) *GormAdapter { - return &GormAdapter{DB: db} -} diff --git a/lightCore/LightCore.go b/lightCore/LightCore.go index 923e6ec..4a63c31 100644 --- a/lightCore/LightCore.go +++ b/lightCore/LightCore.go @@ -13,8 +13,8 @@ type LightCore struct { props []interface{} } -func StartEngine() *LightCore { - gin.SetMode(ConfigValue.Server.RunMode) +func StartEngine(runMode string) *LightCore { + gin.SetMode(runMode) g := &LightCore{gin: gin.New(), props: make([]interface{}, 0)} g.gin.Use(gin.Logger(), gin.Recovery()) return g @@ -23,8 +23,8 @@ func (t *LightCore) GetGin() *gin.Engine { return t.gin } -func (t *LightCore) Launch() { - err := t.gin.Run(fmt.Sprintf(":%d", ConfigValue.Server.HttpPort)) +func (t *LightCore) Launch(port int) { + err := t.gin.Run(fmt.Sprintf(":%d", port)) if err != nil { panic("Gin Launch Error") } diff --git a/lightCore/Start.go b/lightCore/Start.go index fc7f4ba..9a229bb 100644 --- a/lightCore/Start.go +++ b/lightCore/Start.go @@ -26,8 +26,4 @@ func (t *Start) Start() { panic("Server Config Error") } - ConfigValue = t.config - - //初始化数据库 - InitDB() } diff --git a/pkg/mySql/Create.go b/pkg/mySql/Create.go new file mode 100644 index 0000000..d2fd129 --- /dev/null +++ b/pkg/mySql/Create.go @@ -0,0 +1,9 @@ +package mySql + +import ( + "gorm.io/gorm" +) + +func Create(v interface{}, db *gorm.DB) error { + return db.Create(v).Error +} diff --git a/pkg/mySql/Delete.go b/pkg/mySql/Delete.go new file mode 100644 index 0000000..1ccf25b --- /dev/null +++ b/pkg/mySql/Delete.go @@ -0,0 +1,55 @@ +package mySql + +import ( + "errors" + "fmt" + "github.com/Masterminds/squirrel" + "gorm.io/gorm" +) + +type Delete struct { + tableName string + wheres []*Where + db *gorm.DB +} + +func NewDelete(tableName string, db *gorm.DB) *Delete { + return &Delete{tableName: tableName, db: db} +} + +func (t *Delete) WhereRaw(formula string, values ...interface{}) *Delete { + t.wheres = append(t.wheres, NewWhere(formula, values...)) + return t +} + +func (t *Delete) WhereColumn(formula string, values ...interface{}) *Delete { + t.WhereRaw(fmt.Sprintf("`%s` = ?", formula), values...) + return t +} + +func (t *Delete) WhereColumnIn(formula string, values ...interface{}) *Delete { + t.WhereRaw(fmt.Sprintf("`%s` IN ?", formula), values...) + return t +} + +func (t *Delete) Delete() error { + mapper, err := t.Mapper() + if err != nil { + return err + } + return mapper.Exec().Error +} +func (t *Delete) Mapper() (*SqlMapper, error) { + if len(t.wheres) == 0 || t.wheres[0].Formula == "" { + return nil, errors.New("没有where条件不被允许") + } + + squ := squirrel.Delete(fmt.Sprintf("`%s`", t.tableName)) + + //拼接where + for _, where := range t.wheres { + squ = squ.Where(where.Formula, where.Values...) + } + + return Mapper(squ.ToSql()).setDB(t.db), nil +} diff --git a/pkg/mySql/Facade.go b/pkg/mySql/Facade.go new file mode 100644 index 0000000..bf75ede --- /dev/null +++ b/pkg/mySql/Facade.go @@ -0,0 +1,50 @@ +package mySql + +import "gorm.io/gorm" + +type Facade struct { + tableName string + dbFunc func() *gorm.DB +} + +func NewFacade(tableName string, dbFunc func() *gorm.DB) *Facade { + return &Facade{tableName: tableName, dbFunc: dbFunc} +} + +func (t *Facade) NewQuery() *Query { + if t.dbFunc != nil { + return NewQuery(t.tableName).SetDB(t.dbFunc()) + } + return NewQuery(t.tableName) +} + +func (t *Facade) NewUpdate() *Update { + if t.dbFunc != nil { + return NewUpdate(t.tableName).SetDB(t.dbFunc()) + } + return NewUpdate(t.tableName) +} + +func (t *Facade) NewInsert() *Insert { + if t.dbFunc != nil { + return NewInsert(t.tableName).SetDB(t.dbFunc()) + } + return NewInsert(t.tableName) +} + +func (t *Facade) NewDelete() *Delete { + if t.dbFunc != nil { + return NewDelete(t.tableName).SetDB(t.dbFunc()) + } + return NewDelete(t.tableName) +} + +func (t *Facade) Create(val interface{}) error { + if t.dbFunc != nil { + db := t.dbFunc() + if db != nil { + return Create(val, db) + } + } + return Create(val) +} diff --git a/pkg/mySql/Insert.go b/pkg/mySql/Insert.go new file mode 100644 index 0000000..297d3b9 --- /dev/null +++ b/pkg/mySql/Insert.go @@ -0,0 +1,83 @@ +package mySql + +import ( + "fmt" + "github.com/Masterminds/squirrel" + "gorm.io/gorm" + "reflect" + "strings" + "time" +) + +type Insert struct { + tableName string + columns []*Column + db *gorm.DB +} + +func NewInsert(tableName string, db *gorm.DB) *Insert { + return &Insert{tableName: tableName, db: db} +} + +func (t *Insert) AddColumn(column string, value interface{}) *Insert { + t.columns = append(t.columns, NewColumn(fmt.Sprintf("`%s`", column), value)) + return t +} + +func (t *Insert) AddCreatedColumn() *Insert { + return t.AddColumn("created_at", time.Now()) +} + +func (t *Insert) AddUpdatedColumn() *Insert { + return t.AddColumn("updated_at", time.Now()) +} + +func (t *Insert) AddCreatedAndUpdatedColumns() *Insert { + return t.AddCreatedColumn().AddUpdatedColumn() +} + +func (t *Insert) AddColumns(value map[string]interface{}) *Insert { + for s, i := range value { + t.AddColumn(s, i) + } + return t +} + +func (t *Insert) MountColumn(data interface{}) *Insert { + v := reflect.ValueOf(data) + v = v.Elem() + for i := 0; i < v.NumField(); i++ { + column := v.Type().Field(i).Tag.Get("column") + if column != "" { + split := NewStringSplit(strings.ToUpper(column), ":") + split.RunCount1Func(func(str string) { + t.AddColumn(column, v.Field(i).Interface()) + }) + split.RunCount2Func(func(str1, str2 string) { + if str2 == "KEY" { + t.AddColumn(str1, nil) + } else { + t.AddColumn(str1, v.Field(i).Interface()) + } + }) + } + } + return t +} + +func (t *Insert) Insert() error { + return t.Mapper().Exec().Error +} + +func (t *Insert) Mapper() *SqlMapper { + columns := make([]string, 0) + values := make([]interface{}, 0) + + for _, v := range t.columns { + columns = append(columns, v.name) + values = append(values, v.value) + } + + squ := squirrel.Insert(fmt.Sprintf("`%s`", t.tableName)).Columns(columns...).Values(values...) + return Mapper(squ.ToSql()).setDB(t.db) +} diff --git a/pkg/mySql/InsertColumn.go b/pkg/mySql/InsertColumn.go new file mode 100644 index 0000000..cf64eb6 --- /dev/null +++ b/pkg/mySql/InsertColumn.go @@ -0,0 +1,10 @@ +package mySql + +type Column struct { + name string + value interface{} +} + +func NewColumn(name string, value interface{}) *Column { + return &Column{name: name, value: value} +} diff --git a/pkg/mySql/Join.go b/pkg/mySql/Join.go new file mode 100644 index 0000000..4e9ea54 --- /dev/null +++ b/pkg/mySql/Join.go @@ -0,0 +1,11 @@ +package mySql + +type Join struct { + option string + join string + rest []interface{} +} + +func NewJoin(option string, join string, rest []interface{}) *Join { + return &Join{option: option, join: join, rest: rest} +} diff --git a/pkg/mySql/PageStruct.go b/pkg/mySql/PageStruct.go new file mode 100644 index 0000000..a3c110a --- /dev/null +++ b/pkg/mySql/PageStruct.go @@ -0,0 +1,8 @@ +package mySql + +type PageStruct struct { + Total int64 + TotalPage int64 + Page int64 + PageSize int64 +} diff --git a/pkg/mySql/Query.go b/pkg/mySql/Query.go new file mode 100644 index 0000000..5371f89 --- /dev/null +++ b/pkg/mySql/Query.go @@ -0,0 +1,420 @@ +package mySql + +import ( + "fmt" + "github.com/Masterminds/squirrel" + "gorm.io/gorm" + "math" + "reflect" + "strconv" + "strings" +) + +type Query struct { + tableName string + rawColumns []string + autoColumns []string + rawWheres []*Where + autoWheres []*Where + limit int64 + offset int64 + groupBy string + orderBy string + join []*Join + isPageMode bool + page int64 + pageSize int64 + alias string + db *gorm.DB +} + +func NewQuery(tableName string, db *gorm.DB) *Query { + return &Query{ + tableName: tableName, + rawColumns: []string{}, + autoColumns: []string{}, + rawWheres: make([]*Where, 0), + autoWheres: make([]*Where, 0), + limit: 0, + offset: 0, + join: make([]*Join, 0), + isPageMode: false, + page: 1, + pageSize: 30, + db: db, + } +} + +func (t *Query) SetDB(db *gorm.DB) *Query { + t.db = db + return t +} + +func (t *Query) As(alias string) *Query { + t.alias = alias + return t +} + +func (t *Query) Select(columns ...string) *Query { + t.autoColumns = []string{} + for _, column := range columns { + t.autoColumns = append(t.autoColumns, fmt.Sprintf("`%s`", column)) + } + return t +} + +func (t *Query) SelectRow(columns ...string) *Query { + t.rawColumns = columns + return t +} + +func (t *Query) AddSelect(columns ...string) *Query { + for _, v := range columns { + t.autoColumns = append(t.autoColumns, fmt.Sprintf("`%s`", v)) + } + return t +} +func (t *Query) AddSelectRow(columns ...string) *Query { + for _, v := range columns { + t.rawColumns = append(t.rawColumns, v) + } + return t +} + +func (t *Query) GroupBy(s string) *Query { + if find := strings.Contains(s, "."); find { + countSplit := strings.SplitN(s, ".", 2) + if len(countSplit) == 2 { + t.groupBy = fmt.Sprintf("`%s`.`%s`", countSplit[0], countSplit[1]) + } else { + t.groupBy = fmt.Sprintf("`%s`", s) + } + } else { + t.groupBy = fmt.Sprintf("`%s`", s) + } + return t +} +func (t *Query) GroupByRaw(s string) *Query { + t.groupBy = s + return t +} + +func (t *Query) Limit(s int64) *Query { + t.limit = s + return t +} +func (t *Query) Offset(s int64) *Query { + t.offset = s + return t +} + +func (t *Query) Page(p int64) *Query { + t.isPageMode = true + if p == 0 { + p = 1 + } + t.page = p + return t +} + +func (t *Query) PageSize(p int64) *Query { + if p == 0 { + p = 30 + } + t.pageSize = p + return t +} + +func (t *Query) Pages(p int64, s int64) *Query { + return t.Page(p).PageSize(s) +} + +func (t *Query) MountQuery(f func(squ *Query)) *Query { + f(t) + return t +} + +func (t *Query) NotDelete() *Query { + return t.WhereIsNull("deleted_at") +} + +func (t *Query) autoColumnsToRaw() []string { + newColumns := make([]string, 0) + for _, v := range t.autoColumns { + if find := strings.Contains(v, "."); !find { + if t.alias != "" { + newColumns = append(newColumns, fmt.Sprintf("`%s`.%s", t.alias, v)) + } else { + newColumns = append(newColumns, v) + } + } else { + newColumns = append(newColumns, v) + } + } + return newColumns +} + +func (t *Query) getColumns() []string { + all := append(t.autoColumnsToRaw(), t.rawColumns...) + if len(all) == 0 { + return []string{"*"} + } + return all +} + +func (t *Query) getFrom() string { + if t.alias != "" { + return fmt.Sprintf("`%s` AS `%s`", t.tableName, t.alias) + } + return fmt.Sprintf("`%s`", t.tableName) +} + +func (t *Query) getColName(colName string) string { + if t.alias != "" { + return fmt.Sprintf("`%s`.`%s`", t.alias, colName) + } else { + return fmt.Sprintf("`%s`", colName) + } +} + +func (t *Query) mountWhere(squ squirrel.SelectBuilder) squirrel.SelectBuilder { + //先挂载原生数据 + for _, where := range t.rawWheres { + squ = squ.Where(where.Formula, where.Values...) + } + + //挂载需要加工的数据 + for _, where := range t.autoWheres { + squ = squ.Where(where.Formula, where.Values...) + } + + return squ +} + +func (t *Query) mountOther(squ squirrel.SelectBuilder) squirrel.SelectBuilder { + if t.isPageMode { + squ = squ.Offset(uint64(t.pageSize * (t.page - 1))).Limit(uint64(t.pageSize)) + } else { + if t.limit > 0 { + squ = squ.Limit(uint64(t.limit)) + } + if t.offset > 0 { + squ = squ.Offset(uint64(t.limit)) + } + } + + if t.groupBy != "" { + squ = squ.GroupBy(t.groupBy) + } + if t.orderBy != "" { + squ = squ.OrderBy(t.orderBy) + } + + return squ +} +func (t *Query) mountJoin(squ squirrel.SelectBuilder) squirrel.SelectBuilder { + for _, join := range t.join { + if join.option == "left" { + if len(join.rest) == 0 { + squ = squ.LeftJoin(join.join) + } else { + squ = squ.LeftJoin(join.join, join.rest) + } + } else if join.option == "right" { + if len(join.rest) == 0 { + squ = squ.RightJoin(join.join) + } else { + squ = squ.RightJoin(join.join, join.rest) + } + } else if join.option == "inner" { + if len(join.rest) == 0 { + squ = squ.RightJoin(join.join) + } else { + squ = squ.RightJoin(join.join, join.rest) + } + } else { + if len(join.rest) == 0 { + squ = squ.RightJoin(join.join) + } else { + squ = squ.RightJoin(join.join, join.rest) + } + } + } + return squ +} + +func (t *Query) ToSquirrel() squirrel.SelectBuilder { + //获取select + squ := squirrel.Select(t.getColumns()...).From(t.getFrom()) + //组装where + squ = t.mountWhere(squ) + + //组装limit和offset,groupBy和orderBy + squ = t.mountOther(squ) + + //组装join + squ = t.mountJoin(squ) + return squ +} + +func (t *Query) ToGormQuery() *gorm.DB { + return t.toGormQuery(t.ToSquirrel()) +} + +func (t *Query) ToSql() (string, []interface{}, error) { + return t.ToSquirrel().ToSql() +} + +func (t *Query) toGormQuery(squ squirrel.SelectBuilder) *gorm.DB { + return Mapper(squ.ToSql()).setDB(t.db).Query() +} + +func (t *Query) Find(list interface{}) error { + return t.ToGormQuery().Find(list).Error +} + +func (t *Query) Take(info interface{}) error { + t.limit = 1 + return t.ToGormQuery().Take(info).Error +} + +func (t *Query) GetTotal() int64 { + //只组装where + squ := squirrel.Select("count(*)").From(t.getFrom()) + //组装where + squ = t.mountWhere(squ) + + var count int64 + t.toGormQuery(squ).Scan(&count) + return count +} + +func (t *Query) GetRowCount() int64 { + //只组装where + squ := squirrel.Select("count(*)").From(t.getFrom()) + //组装where + squ = t.mountWhere(squ) + //组装groupBy + if t.groupBy != "" { + squ = squ.GroupBy(t.groupBy) + } + var count int64 + t.toGormQuery(squ).Count(&count) + return count +} + +func (t *Query) GetSum(column string) int64 { + //只组装where + squ := squirrel.Select(fmt.Sprintf("SUM(`%s`)", column)).From(t.getFrom()) + //组装where + squ = t.mountWhere(squ) + var sum int64 + t.toGormQuery(squ).Scan(&sum) + return sum +} + +func (t *Query) GetSumInterface(column string, value interface{}) { + //只组装where + squ := squirrel.Select(fmt.Sprintf("SUM(`%s`)", column)).From(t.getFrom()) + //组装where + squ = t.mountWhere(squ) + t.toGormQuery(squ).Scan(&value) +} + +func (t *Query) PageFind(list interface{}) (*PageStruct, error) { + err1 := t.Find(list) + total := t.GetTotal() + p := &PageStruct{ + Total: total, + TotalPage: 0, + Page: t.page, + PageSize: t.pageSize, + } + + totalPage, err := strconv.ParseFloat(fmt.Sprintf("%.5f", float64(total)/float64(t.pageSize)), 64) + if err == nil { + p.TotalPage = int64(math.Ceil(totalPage)) + } else { + p.TotalPage = (total / p.PageSize) + 1 + } + + return p, err1 +} + +func (t *Query) MountWhereForReflect(data interface{}) *Query { + v := reflect.ValueOf(data) + v = v.Elem() + for i := 0; i < v.NumField(); i++ { + where := v.Type().Field(i).Tag.Get("where") + if where != "" && !isBlank(v.Field(i)) { + split := NewStringSplit(where, ":") + //如果是1段 + split.RunCount1Func(func(whereColName string) { + t.WhereRaw(fmt.Sprintf("%s = ?", t.getColName(whereColName)), v.Field(i).Interface()) + }) + + //如果是2段 + split.RunCount2Func(func(whereColName, whereOperation string) { + //str2的值LIKE_BOTH、LIKE、BOOL等 + whereOperationSplit := NewStringSplit(strings.ToUpper(whereOperation), "_") + whereOperationSplit.RunCount1Func(func(operation string) { + //这里的operation是LIKE_BOTH的LIKE + if operation == "LIKE" { + t.WhereRaw( + fmt.Sprintf("%s LIKE ?", t.getColName(whereColName)), + v.Field(i).Interface(), + ) + } + if operation == "BOOL" { + if v.Field(i).Interface() == "yes" { + t.WhereRaw(fmt.Sprintf("%s = ?", t.getColName(whereColName)), 1) + } + if v.Field(i).Interface() == "no" { + t.WhereRaw(fmt.Sprintf("%s = ?", t.getColName(whereColName)), 0) + } + } + }) + whereOperationSplit.RunCount2Func(func(operation, operation2 string) { + //这里的operation是LIKE_BOTH的LIKE,operation2是BOTH + if operation == "LIKE" { + if operation2 == "BOTH" { + t.WhereRaw( + fmt.Sprintf("%s LIKE ?", t.getColName(whereColName)), + fmt.Sprintf("%s%s%s", "%", v.Field(i).Interface(), "%"), + ) + } + if operation2 == "LEFT" { + t.WhereRaw( + fmt.Sprintf("%s LIKE ?", t.getColName(whereColName)), + fmt.Sprintf("%s%s", "%", v.Field(i).Interface()), + ) + } + if operation2 == "RIGHT" { + t.WhereRaw( + fmt.Sprintf("%s LIKE ?", t.getColName(whereColName)), + fmt.Sprintf("%s%s", v.Field(i).Interface(), "%"), + ) + } + } + }) + }) + + } + } + return t +} +func (t *Query) SelectAllForReflect(data interface{}) *Query { + v := reflect.ValueOf(data) + v = v.Elem() + for i := 0; i < v.NumField(); i++ { + column := v.Type().Field(i).Tag.Get("column") + if column != "" { + //取第一个添加到列 + split := NewStringSplit(column, ":") + split.RunIndexFunc(0, func(str string) { + t.AddSelect(str) + }) + } + } + return t +} diff --git a/pkg/mySql/QueryJoin.go b/pkg/mySql/QueryJoin.go new file mode 100644 index 0000000..d171112 --- /dev/null +++ b/pkg/mySql/QueryJoin.go @@ -0,0 +1,53 @@ +package mySql + +import ( + "fmt" + "strings" +) + +func (t *Query) Join(join string, rest ...interface{}) *Query { + t.join = append(t.join, NewJoin("", join, rest)) + return t +} + +func (t *Query) LeftJoin(join string, rest ...interface{}) *Query { + t.join = append(t.join, NewJoin("left", join, rest)) + return t +} + +func (t *Query) RightJoin(join string, rest ...interface{}) *Query { + t.join = append(t.join, NewJoin("right", join, rest)) + return t +} + +func (t *Query) InnerJoin(join string, rest ...interface{}) *Query { + t.join = append(t.join, NewJoin("inner", join, rest)) + return t +} + +func (t *Query) LeftJoinOn(tableName string, pk string, pk2 string, columns ...string) *Query { + as := string(rune(len(t.join) + 98)) + + for _, column := range columns { + //看一下有没有as + if find := strings.Contains(column, " as "); find { + //劈开前面一段和后面一段 + countSplit := strings.SplitN(column, " as ", 2) + if len(countSplit) == 2 { + t.AddSelectRow(fmt.Sprintf("`%s`.`%s` as `%s`", as, countSplit[0], countSplit[1])) + } else { + t.AddSelectRow(column) + } + + } else { + t.AddSelectRow(fmt.Sprintf("`%s`.`%s`", as, column)) + } + + } + if t.alias == "" { + t.LeftJoin(fmt.Sprintf("`%s` `%s` ON `%s`.`%s` = `%s`.`%s`", tableName, as, as, pk, t.tableName, pk2)) + } else { + t.LeftJoin(fmt.Sprintf("`%s` `%s` ON `%s`.`%s` = `%s`.`%s`", tableName, as, as, pk, t.alias, pk2)) + } + return t +} diff --git a/pkg/mySql/QueryManager.go b/pkg/mySql/QueryManager.go new file mode 100644 index 0000000..73c67ce --- /dev/null +++ b/pkg/mySql/QueryManager.go @@ -0,0 +1,91 @@ +package mySql + +import ( + "errors" + "gorm.io/gorm" + "reflect" +) + +// 因为有大量的是简单的通过where查询一条数据的,例如查询某个用户的资料,所以封装这个工具类简化操作,用法与query保持一致 +type QueryManager struct { + tableName string + wheres []*QueryManagerWhere + errorText string + error error +} + +type QueryManagerWhere struct { + colName string + value interface{} + emptyCheck bool +} + +func NewQueryManager(tableName string) *QueryManager { + return &QueryManager{ + tableName: tableName, + wheres: make([]*QueryManagerWhere, 0), + } +} + +func (t *QueryManager) SetErrorText(text string) *QueryManager { + t.errorText = text + return t +} + +func (t *QueryManager) Where(colName string, value interface{}) *QueryManager { + t.wheres = append(t.wheres, &QueryManagerWhere{ + colName: colName, + value: value, + emptyCheck: true, + }) + return t +} +func (t *QueryManager) WhereRow(colName string, value interface{}, emptyCheck bool) *QueryManager { + t.wheres = append(t.wheres, &QueryManagerWhere{ + colName: colName, + value: value, + emptyCheck: emptyCheck, + }) + return t +} + +func (t *QueryManager) Take(data interface{}) error { + if len(t.wheres) == 0 { + return errors.New("not where") + } + + for colName := range t.wheres { + if isBlank(reflect.ValueOf(t.wheres[colName])) { + //如果是空值 + return t.getEmptyError() + } + } + + query := NewQuery(t.tableName) + for _, where := range t.wheres { + if where.emptyCheck { + //检查空值 + if isBlank(reflect.ValueOf(where.value)) { + return t.getEmptyError() + } + } + query.Where(where.colName, where.value) + } + + err := query.Take(data) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return t.getEmptyError() + } + } + + return err +} + +func (t *QueryManager) getEmptyError() error { + if t.errorText != "" { + return errors.New(t.errorText) + } else { + return errors.New("不存在") + } +} diff --git a/pkg/mySql/QueryOrderBy.go b/pkg/mySql/QueryOrderBy.go new file mode 100644 index 0000000..d4bd18d --- /dev/null +++ b/pkg/mySql/QueryOrderBy.go @@ -0,0 +1,42 @@ +package mySql + +import ( + "fmt" + "strings" +) + +func (t *Query) OrderByRaw(s string) *Query { + t.orderBy = s + return t +} +func (t *Query) OrderBy(s string, b string) *Query { + //看有没有. + countSplit := strings.SplitN(s, ".", 2) + if len(countSplit) == 2 { + t.orderBy = fmt.Sprintf("`%s`.`%s` %s", countSplit[0], countSplit[1], b) + } else { + t.orderBy = fmt.Sprintf("`%s` %s", s, b) + } + return t +} + +func (t *Query) OrderByDesc(s string) *Query { + t.OrderBy(s, "DESC") + return t +} + +func (t *Query) OrderByAsc(s string) *Query { + t.OrderBy(s, "ASC") + return t +} + +func (t *Query) OrderIsByDesc(isDesc bool, s string) *Query { + if s != "" { + if isDesc { + t.OrderByDesc(s) + } else { + t.OrderByAsc(s) + } + } + return t +} diff --git a/pkg/mySql/QueryWhere.go b/pkg/mySql/QueryWhere.go new file mode 100644 index 0000000..475f59d --- /dev/null +++ b/pkg/mySql/QueryWhere.go @@ -0,0 +1,110 @@ +package mySql + +import ( + "fmt" + "strings" +) + +func (t *Query) makeColName(colName string) string { + //这里的colName其实还没有``包裹 + //如果存在.那就是复合字段 + if find := strings.Contains(colName, "."); find { + countSplit := strings.SplitN(colName, ".", 2) + if len(countSplit) == 2 { + //因为到了where会无脑加上``包裹,所以两侧``是不需要加的 + return fmt.Sprintf("%s`.`%s", countSplit[0], countSplit[1]) + } + } + return colName +} + +func (t *Query) WhereRaw(formula string, values ...interface{}) *Query { + t.rawWheres = append(t.rawWheres, NewWhere(formula, values...)) + return t +} + +func (t *Query) Where(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewEqWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereEq(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewEqWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereNeq(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewNeqWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereGt(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewGtWhere(t.makeColName(colName), value)) + return t +} +func (t *Query) WhereEgt(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewEgtWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereLt(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewLtWhere(t.makeColName(colName), value)) + return t +} +func (t *Query) WhereElt(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewEltWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereNotLike(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewNotLikeWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereLike(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewLikeWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereBetween(colName string, value1 interface{}, value2 interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewBetweenWhere(t.makeColName(colName), value1, value2)) + return t +} + +func (t *Query) WhereNotBetween(colName string, value1 interface{}, value2 interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewNotBetweenWhere(t.makeColName(colName), value1, value2)) + return t +} + +func (t *Query) WhereIn(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewInWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereNotIn(colName string, value interface{}) *Query { + t.autoWheres = append(t.autoWheres, NewNotInWhere(t.makeColName(colName), value)) + return t +} + +func (t *Query) WhereIsNull(colName string) *Query { + t.autoWheres = append(t.autoWheres, NewIsNullWhere(t.makeColName(colName))) + return t +} + +func (t *Query) WhereIsNotNull(colName string) *Query { + t.autoWheres = append(t.autoWheres, NewIsNotNullWhere(t.makeColName(colName))) + return t +} + +func (t *Query) Wheres(value map[string]interface{}) *Query { + for s, i := range value { + t.Where(s, i) + } + return t +} + +func (t *Query) WhereBetweenFunc(colName string, f func() (start interface{}, end interface{})) *Query { + start, end := f() + t.WhereBetween(colName, start, end) + return t +} diff --git a/pkg/mySql/Reflect.go b/pkg/mySql/Reflect.go new file mode 100644 index 0000000..3d4ce52 --- /dev/null +++ b/pkg/mySql/Reflect.go @@ -0,0 +1,24 @@ +package mySql + +import ( + "reflect" +) + +// 判断是不是空值 +func isBlank(value reflect.Value) bool { + switch value.Kind() { + case reflect.String: + return value.Len() == 0 + case reflect.Bool: + return !value.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return value.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return value.Uint() == 0 + case reflect.Float32, reflect.Float64: + return value.Float() == 0 + case reflect.Interface, reflect.Ptr: + return value.IsNil() + } + return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface()) +} diff --git a/pkg/mySql/SqlMapper.go b/pkg/mySql/SqlMapper.go new file mode 100644 index 0000000..1b40a5c --- /dev/null +++ b/pkg/mySql/SqlMapper.go @@ -0,0 +1,78 @@ +package mySql + +import ( + "errors" + "fmt" + "gorm.io/gorm" +) + +type SqlMapper struct { + Sql string + Args []interface{} + db *gorm.DB +} + +func (t *SqlMapper) setDB(db *gorm.DB) *SqlMapper { + t.db = db + return t +} + +// 查询 +func (t *SqlMapper) Query() *gorm.DB { + return t.db.Raw(t.Sql, t.Args...) +} + +func (t *SqlMapper) Exec() *gorm.DB { + return t.db.Exec(t.Sql, t.Args...) +} + +func NewSqlMapper(sql string, args []interface{}) *SqlMapper { + return &SqlMapper{Sql: sql, Args: args} +} + +func Mapper(sql string, args []interface{}, err error) *SqlMapper { + if err != nil { + panic(err.Error()) + } + return NewSqlMapper(sql, args) +} + +type SqlMappers []*SqlMapper + +func Mappers(sqlMappers ...*SqlMapper) (list SqlMappers) { + list = sqlMappers + return +} +func (t SqlMappers) apply(tx *gorm.DB) { + for _, sql := range t { + sql.setDB(tx) + } +} +func (t SqlMappers) Exec(f func() error) error { + if len(t) == 0 { + return errors.New("无Mapper") + } + //其实是以第一个为准 + return t[0].db.Transaction(func(tx *gorm.DB) error { + t.apply(tx) + return f() + }) +} + +func (t SqlMappers) ExecTransaction() error { + //其实是以第一个为准 + return t[0].db.Transaction(func(tx *gorm.DB) error { + fmt.Println("事务开始") + for _, sql := range t { + sql.setDB(tx) + err := sql.Exec().Error + if err != nil { + fmt.Println("事务结束(失败)") + return err + } + } + fmt.Println("事务成功") + return nil + }) + +} diff --git a/pkg/mySql/StringSplit.go b/pkg/mySql/StringSplit.go new file mode 100644 index 0000000..1090e0c --- /dev/null +++ b/pkg/mySql/StringSplit.go @@ -0,0 +1,56 @@ +package mySql + +import ( + "strings" +) + +type StringSplit struct { + str string + sep string +} + +func NewStringSplit(str string, sep string) *StringSplit { + return &StringSplit{str: str, sep: sep} +} + +func (t *StringSplit) chooseIndexStr(index int) (string, bool) { + //劈开 + countSplit := strings.Split(t.str, t.sep) + + //获取对应的字符串,index是从0开始算。 + if len(countSplit) <= index { + return "", false + } + + return countSplit[index], true +} + +// RunIndexFunc 取第index个,从0开始数,执行。 +func (t *StringSplit) RunIndexFunc(index int, f func(str string)) { + str, exist := t.chooseIndexStr(index) + if exist { + f(str) + } +} + +// RunCountFunc 如果分割出来是count个则执行 +func (t *StringSplit) RunCountFunc(count int, f func(strArr []string)) { + countSplit := strings.Split(t.str, t.sep) + if len(countSplit) == count { + f(countSplit) + } +} + +// RunCount1Func 常用方法封装,快捷方法,count=1 +func (t *StringSplit) RunCount1Func(f func(str string)) { + t.RunCountFunc(1, func(strArr []string) { + f(strArr[0]) + }) +} + +// RunCount2Func 常用方法封装,快捷方法,count=2 +func (t *StringSplit) RunCount2Func(f func(str1, str2 string)) { + t.RunCountFunc(2, func(strArr []string) { + f(strArr[0], strArr[1]) + }) +} diff --git a/pkg/mySql/Update.go b/pkg/mySql/Update.go new file mode 100644 index 0000000..9cb6e4f --- /dev/null +++ b/pkg/mySql/Update.go @@ -0,0 +1,127 @@ +package mySql + +import ( + "errors" + "fmt" + "github.com/Masterminds/squirrel" + "gorm.io/gorm" + "reflect" + "strings" + "time" +) + +type Update struct { + tableName string + columns []*Column + wheres []*Where + db *gorm.DB +} + +func NewUpdate(tableName string, db *gorm.DB) *Update { + return &Update{tableName: tableName, db: db} +} + +func (t *Update) MountColumn(data interface{}) *Update { + v := reflect.ValueOf(data) + v = v.Elem() + for i := 0; i < v.NumField(); i++ { + column := v.Type().Field(i).Tag.Get("column") + if column != "" { + countSplit := strings.SplitN(column, ":", 2) + if len(countSplit) == 2 { + if countSplit[1] != "key" { + t.AddColumn(countSplit[0], v.Field(i).Interface()) + } else { + t.Where(countSplit[0], v.Field(i).Interface()) + } + } else { + t.AddColumn(column, v.Field(i).Interface()) + } + } + } + return t +} + +func (t *Update) AddColumn(column string, value interface{}) *Update { + t.columns = append(t.columns, NewColumn(fmt.Sprintf("`%s`", column), value)) + return t +} + +func (t *Update) AddColumns(m map[string]interface{}) *Update { + for s, i := range m { + t.AddColumn(s, i) + } + return t +} + +func (t *Update) AddColumnInc(column string, inc uint) *Update { + t.columns = append(t.columns, NewColumn( + fmt.Sprintf("`%s`", column), + squirrel.Expr(fmt.Sprintf("`%s` + %d", column, inc)), + )) + return t +} + +func (t *Update) AddColumnDec(column string, dec uint) *Update { + t.columns = append(t.columns, NewColumn( + fmt.Sprintf("`%s`", column), + squirrel.Expr(fmt.Sprintf("`%s` - %d", column, dec)), + )) + return t +} + +func (t *Update) AddCreatedColumn() *Update { + t.AddColumn("created_at", time.Now()) + return t +} + +func (t *Update) AddUpdatedColumn() *Update { + t.AddColumn("updated_at", time.Now()) + return t +} +func (t *Update) AddDeletedColumn() *Update { + t.AddColumn("deleted_at", time.Now()) + return t +} +func (t *Update) WhereRaw(formula string, values ...interface{}) *Update { + t.wheres = append(t.wheres, NewWhere(formula, values...)) + return t +} + +func (t *Update) Where(formula string, values ...interface{}) *Update { + t.WhereRaw(fmt.Sprintf("`%s` = ?", formula), values...) + return t +} + +func (t *Update) Update() error { + mapper, err := t.Mapper() + if err != nil { + return err + } + return mapper.Exec().Error +} + +func (t *Update) toSqu() (squirrel.UpdateBuilder, error) { + if len(t.wheres) == 0 || t.wheres[0].Formula == "" { + return squirrel.UpdateBuilder{}, errors.New("没有where条件不被允许") + } + + squ := squirrel.Update(fmt.Sprintf("`%s`", t.tableName)) + for _, v := range t.columns { + squ = squ.Set(v.name, v.value) + } + + //拼接where + for _, where := range t.wheres { + squ = squ.Where(where.Formula, where.Values...) + } + return squ, nil +} + +func (t *Update) Mapper() (*SqlMapper, error) { + squ, err := t.toSqu() + if err != nil { + return nil, err + } + return Mapper(squ.ToSql()).setDB(t.db), nil +} diff --git a/pkg/mySql/Where.go b/pkg/mySql/Where.go new file mode 100644 index 0000000..af761af --- /dev/null +++ b/pkg/mySql/Where.go @@ -0,0 +1,115 @@ +package mySql + +import "fmt" + +type Where struct { + Formula string + Values []interface{} +} + +func NewWhere(formula string, values ...interface{}) *Where { + return &Where{ + Formula: formula, + Values: values, + } +} + +func NewWheres(where ...*Where) []*Where { + return where +} + +func NewEqWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` = ?", colName), + Values: []interface{}{value}, + } +} + +func NewNeqWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` <> ?", colName), + Values: []interface{}{value}, + } +} + +func NewGtWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` > ?", colName), + Values: []interface{}{value}, + } +} +func NewEgtWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` >= ?", colName), + Values: []interface{}{value}, + } +} + +func NewLtWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` < ?", colName), + Values: []interface{}{value}, + } +} +func NewEltWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` <= ?", colName), + Values: []interface{}{value}, + } +} + +func NewNotLikeWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` NOT LIKE ?", colName), + Values: []interface{}{value}, + } +} + +func NewLikeWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` LIKE ?", colName), + Values: []interface{}{value}, + } +} + +func NewBetweenWhere(colName string, value1 interface{}, value2 interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("(`%s` BETWEEN ? AND ?)", colName), + Values: []interface{}{value1, value2}, + } +} + +func NewNotBetweenWhere(colName string, value1 interface{}, value2 interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("(`%s` NOT BETWEEN ? AND ?)", colName), + Values: []interface{}{value1, value2}, + } +} + +func NewInWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` IN ?", colName), + Values: []interface{}{value}, + } +} + +func NewNotInWhere(colName string, value interface{}) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` NOT IN ?", colName), + Values: []interface{}{value}, + } +} + +func NewIsNullWhere(colName string) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` IS NULL", colName), + Values: []interface{}{}, + } +} + +func NewIsNotNullWhere(colName string) *Where { + return &Where{ + Formula: fmt.Sprintf("`%s` IS NOT NULL ?", colName), + Values: []interface{}{}, + } +} diff --git a/test/start_test.go b/test/start_test.go index 63aa3de..0f0d818 100644 --- a/test/start_test.go +++ b/test/start_test.go @@ -1,8 +1,17 @@ package test import ( + "code.zhecent.com/gopkg/light-core/lightCore" + "github.com/gin-gonic/gin" "testing" ) func TestStart(t *testing.T) { + + lightCore.StartEngine("debug"). + //LoadHtml("view/*"). + Mounts([]*lightCore.Routers{}). + SetNoRoute(func(context *gin.Context) { + }). + Launch(8888) }