From 5fedf4a955b02c09aec818c29301adbaff3e3a70 Mon Sep 17 00:00:00 2001 From: xiongjun ai Date: Wed, 17 Jan 2024 17:23:08 +0800 Subject: [PATCH] fix word by golint --- .golangci.yaml | 305 +++++++++++++++++++++++++++++++++++++++++ constants/constants.go | 11 +- constants/keyword.go | 44 +++--- gplus/dao.go | 44 +++--- gplus/query.go | 30 ++-- gplus/segment.go | 10 +- gplus/tool.go | 20 ++- tests/dao_test.go | 4 +- tests/delete_test.go | 2 +- tests/insert_test.go | 2 +- tests/select_test.go | 2 +- tests/update_test.go | 2 +- tests/utils.go | 7 +- 13 files changed, 403 insertions(+), 80 deletions(-) create mode 100644 .golangci.yaml diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..3978daf --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,305 @@ +linters: + # Disable all linters. + # Default: false + disable-all: false + # Enable specific linter + # https://golangci-lint.run/usage/linters/#enabled-by-default + enable: + - asasalint # Check for pass []any as any in variadic func(...any). 检查是否在可变参数函数 func(...any) 中传递了 []any 作为 any 参数。 + - gofmt # Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification. + - gofumpt # Gofumpt checks whether code was gofumpt-ed. Gofumpt检查代码是否已被gofumpt处理过 + - bodyclose # Checks whether HTTP response body is closed successfully. 检查HTTP响应体是否已成功关闭。 + - dupl # Tool for code clone detection. 用于代码克隆检测的工具。 + - errname # Checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error. 检查哨兵错误是否以Err为前缀,错误类型是否以Error为后缀。 + - errorlint # Errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. Errorlint是一个静态代码分析工具,可以用来查找会在Go 1.13引入的错误包装方案中引起问题的代码。 + - errcheck # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases. Errcheck是一个用于检查Go程序中未处理错误的程序。在某些情况下,这些未处理的错误可能是关键性的错误。 + - funlen # Tool for detection of long functions. 检查函数长度 + - gosimple # Linter for Go source code that specializes in simplifying code. 专门用于简化Go代码的静态代码分析工具。 + - gocyclo # Computes and checks the cyclomatic complexity of functions. 计算并检查函数的圈复杂度 + - goconst # Finds repeated strings that could be replaced by a constant. 找到可以被常量替换的重复字符串。 + - gosec # Inspects source code for security problems. 检查源代码中的安全问题 + - govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string. Vet检查Go源代码并报告可疑的构造,例如Printf调用的参数与格式字符串不对齐。 + - ineffassign # Detects when assignments to existing variables are not used. 检测对现有变量的赋值是否未被使用。 + - staticcheck # Staticcheck is a go vet on steroids, applying a ton of static analysis checks. Staticcheck就像是强化版的go vet,它可以应用大量的静态分析检查。 + - typecheck # Like the front-end of a Go compiler, parses and type-checks Go code. 像Go编译器的前端一样,解析并对Go代码进行类型检查。 + - unused # Checks Go code for unused constants, variables, functions and types. 检查Go代码中未使用的常量、变量、函数和类型。 + - unconvert # Remove unnecessary type conversions. 移除不必要的类型转换。 + - usestdlibvars # A linter that detect the possibility to use variables/constants from the Go standard library. 一个可以检测出可能使用Go标准库中的变量/常量的静态代码分析工具。 + - varnamelen # Checks that the length of a variable's name matches its scope. 检查变量名称的长度是否与其作用域匹配。 + - whitespace # Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc. Whitespace是一个静态代码分析工具,用于检查函数、if、for等语句开始和结束处是否有不必要的空行。 + - revive # Carry out the stylistic conventions put forth in Effective Go and CodeReviewComments. 执行《Effective Go》和《CodeReviewComments》中提出的风格约定 + + # Enable all available linters. + # Default: false + enable-all: false + disable: + #- asasalint + - gci + - asciicheck + - bidichk + - depguard + - containedctx + - contextcheck + - cyclop + - decorder + - dogsled + #- dupl + - dupword + - durationcheck + - errchkjson + - execinquery + - exhaustive + - exhaustivestruct + - exhaustruct + - exportloopref + - forbidigo + - forcetypeassert + #- funlen + - ginkgolinter + - gocheckcompilerdirectives + - gochecknoglobals + - gochecknoinits + - gochecksumtype + - gocognit + #- goconst + - gocritic + #- gocyclo + - godot + - godox + - goerr113 + - goheader + - goimports + #- golint + - gomnd + - gomoddirectives + - gomodguard + - goprintffuncname + #- gosec + #- gosimple + - gosmopolitan + #- govet + - grouper + - ifshort + - importas + - inamedparam + #- ineffassign + - interfacebloat + - interfacer + - ireturn + - lll + - loggercheck + - maintidx + - makezero + - maligned + - mirror + - misspell + - musttag + - nakedret + - nestif + - nilerr + - nilnil + - nlreturn + - noctx + - nolintlint + - nonamedreturns + - nosnakecase + - nosprintfhostport + - paralleltest + - perfsprint + - prealloc + - predeclared + - promlinter + - protogetter + - reassign + #- revive + - rowserrcheck + #- scopelint + - sloglint + - sqlclosecheck + #- staticcheck + #- structcheck + - stylecheck + - tagalign + - tagliatelle + - tenv + - testableexamples + - testifylint + - testpackage + - thelper + - tparallel + #- typecheck + #- unconvert + - unparam + #- unused + #- usestdlibvars + #- varcheck + #- varnamelen + - wastedassign + #- whitespace + - wrapcheck + - wsl + - zerologlint + + # Enable presets. + # https://golangci-lint.run/usage/linters + presets: + - bugs + - comment + - error + - format + - metalinter + - module + - performance + - sql + - style + - unused + - test + - import + - complexity + # Run only fast linters from enabled linters set (first run won't be fast) + # Default: false + fast: true +output: + format: colored-line-number # colored-line-number|line-number|json|colored-tab|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity + print-issued-lines: true + print-linter-name: true + uniq-by-line: true + path-prefix: "" + sort-results: true + +linters-settings: + govet: + check-shadowing: true + gocyclo: + min-complexity: 20 + dupl: + threshold: 150 + goconst: + min-len: 2 + min-occurrences: 2 + errcheck: + # Report about not checking of errors in type assertions: `a := b.(MyStruct)`. + # Such cases aren't reported by default. + # Default: false + check-type-assertions: false + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`. + # Such cases aren't reported by default. + # Default: false + check-blank: true + # DEPRECATED comma-separated list of pairs of the form pkg:regex + # + # the regex is used to ignore names within pkg. (default "fmt:.*"). + # see https://github.com/kisielk/errcheck#the-deprecated-method for details + ignore: fmt:.*,io/ioutil:^Read.* + # To disable the errcheck built-in exclude list. + # See `-excludeonly` option in https://github.com/kisielk/errcheck#excluding-functions for details. + # Default: false + disable-default-exclusions: true + # DEPRECATED use exclude-functions instead. + # + # Path to a file containing a list of functions to exclude from checking. + # See https://github.com/kisielk/errcheck#excluding-functions for details. + exclude: + # List of functions to exclude from checking, where each entry is a single function to exclude. + # See https://github.com/kisielk/errcheck#excluding-functions for details. + exclude-functions: + - io/ioutil.ReadFile + - io.Copy(*bytes.Buffer) + - io.Copy(os.Stdout) + + varnamelen: + # The longest distance, in source lines, that is being considered a "small scope." (defaults to 5) + # Variables used in at most this many lines will be ignored. + max-distance: 5 + # The minimum length of a variable's name that is considered "long." (defaults to 3) + # Variable names that are at least this long will be ignored. + min-name-length: 1 + # Check method receivers. (defaults to false) + check-receiver: false + # Check named return values. (defaults to false) + check-return: false + # Check type parameters. (defaults to false) + check-type-param: false + # Ignore "ok" variables that hold the bool return value of a type assertion. (defaults to false) + ignore-type-assert-ok: false + # Ignore "ok" variables that hold the bool return value of a map index. (defaults to false) + ignore-map-index-ok: false + # Ignore "ok" variables that hold the bool return value of a channel receive. (defaults to false) + ignore-chan-recv-ok: false + # Optional list of variable names that should be ignored completely. (defaults to empty list) + ignore-names: + - err + - c + + # Optional list of variable declarations that should be ignored completely. (defaults to empty list) + # Entries must be in one of the following forms (see below for examples): + # - for variables, parameters, named return values, method receivers, or type parameters: + # ( can also be a pointer/slice/map/chan/...) + # - for constants: const + ignore-decls: + - c echo.Context + - c *gin.Context + - t testing.T + - f *foo.Bar + - e error + - i int + - j int + - const C + - T any + - m map[string]int + - db *gorm.DB + - j *JWT + revive: + ignore-generated-header: false + severity: warning + confidence: 0.8 + rules: + - name: exported + - name: time-naming + - name: package-comments + - name: blank-imports + - name: file-header + - name: if-return + - name: increment-decrement + - name: var-naming # 校验变量名不是驼峰 + severity: warning + disabled: false + arguments: + - ["ID"] # AllowList + - ["VM"] # DenyList + - - upperCaseConst: true + - name: var-declaration + - name: unexported-return + - name: indent-error-flow + - name: error-strings + - name: range + - name: superfluous-else + - name: bool-literal-in-expr + + funlen: + # Checks the number of lines in a function. + # If lower than 0, disable the check. + # Default: 60 + lines: 100 + # Checks the number of statements in a function. + # If lower than 0, disable the check. + # Default: 40 + statements: 40 + # Ignore comments when counting lines. + # Default false + ignore-comments: true + +issues: + exclude-use-default: false + exclude-rules: + - path: _test\.go$ + linters: + - all + - linters: [errcheck] + text: "Error return value of .((os\\.)?std(out|err)\\.Write|fmt\\.Fprint). is not checked" + - linters: ["revive", "goconst"] + path: .*_test\.go + - linters: ["varnamelen", "errcheck", "revive", "staticcheck"] + path: .*_test\.go + #new-from-rev: HEAD + #new-from-rev: f1093815799644c1d4c286bbc0e0123c280bd80f diff --git a/constants/constants.go b/constants/constants.go index 4fe8d1d..4a2345c 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -1,3 +1,4 @@ +// Package constants 常量值定义 /* * Licensed to the AcmeStack under one or more contributor license * agreements. See the NOTICE file distributed with this work for @@ -14,12 +15,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package constants const ( - Comma = "," - LeftBracket = "(" - RightBracket = ")" - DefaultPrimaryName = "id" + Comma = "," // nolint + LeftBracket = "(" // nolint + RightBracket = ")" // nolint + DefaultPrimaryName = "id" // nolint + NullString = "null" // nolint ) diff --git a/constants/keyword.go b/constants/keyword.go index ae25ea4..d96950d 100644 --- a/constants/keyword.go +++ b/constants/keyword.go @@ -18,26 +18,26 @@ package constants const ( - And = "AND" - Or = "OR" - In = "IN" - Not = "NOT" - Like = "LIKE" - Eq = "=" - Ne = "<>" - Gt = ">" - Ge = ">=" - Lt = "<" - Le = "<=" - IsNull = "IS NULL" - IsNotNull = "IS NOT NULL" - Between = "BETWEEN" - Desc = "DESC" - Asc = "ASC" - As = "AS" - SUM = "SUM" - AVG = "AVG" - MAX = "MAX" - MIN = "MIN" - COUNT = "COUNT" + And = "AND" // nolint + Or = "OR" // nolint + In = "IN" // nolint + Not = "NOT" // nolint + Like = "LIKE" // nolint + Eq = "=" // nolint + Ne = "<>" // nolint + Gt = ">" // nolint + Ge = ">=" // nolint + Lt = "<" // nolint + Le = "<=" // nolint + IsNull = "IS NULL" // nolint + IsNotNull = "IS NOT NULL" // nolint + Between = "BETWEEN" // nolint + Desc = "DESC" // nolint + Asc = "ASC" // nolint + As = "AS" // nolint + SUM = "SUM" // nolint + AVG = "AVG" // nolint + MAX = "MAX" // nolint + MIN = "MIN" // nolint + COUNT = "COUNT" // nolint ) diff --git a/gplus/dao.go b/gplus/dao.go index 769efea..1605062 100644 --- a/gplus/dao.go +++ b/gplus/dao.go @@ -36,10 +36,12 @@ var ( defaultBatchSize = 1000 ) +// Init 初始化DB func Init(db *gorm.DB) { globalDb = db } +// Page 分页查询结构 type Page[T any] struct { Current int `json:"page"` // 页码 Size int `json:"pageSize"` // 每页大小 @@ -49,20 +51,25 @@ type Page[T any] struct { RecordsMap []T `json:"listMap"` } +// Dao 通用dao层 type Dao[T any] struct{} +// NewQuery 构造一个查询 func (dao Dao[T]) NewQuery() (*QueryCond[T], *T) { return NewQuery[T]() } +// NewPage 构造一个分页查询 func NewPage[T any](current, size int) *Page[T] { return &Page[T]{Current: current, Size: size} } +// Comparable 可比较的接口 type Comparable interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64 | time.Time } +// StreamingPage 流式分页查询结构 type StreamingPage[T any, V Comparable] struct { ColumnName any `json:"columnName"` // 进行分页的列字段名称 StartValue V `json:"startValue"` // 分页起始值 @@ -73,6 +80,7 @@ type StreamingPage[T any, V Comparable] struct { RecordsMap []T `json:"recordsMap"` // 查询记录Map } +// NewStreamingPage 流式分页查询 func NewStreamingPage[T any, V Comparable](columnName any, startValue V, limit int) *StreamingPage[T, V] { return &StreamingPage[T, V]{ ColumnName: columnName, @@ -233,26 +241,26 @@ func PluckDistinct[T any, R any](column string, q *QueryCond[T], opts ...OptionF return results, resultDb } -// SelectListBySql 按任意SQL执行,指定返回类型数组 -func SelectListBySql[R any](querySql string, opts ...OptionFunc) ([]*R, *gorm.DB) { +// SelectListBySQL 按任意SQL执行,指定返回类型数组 +func SelectListBySQL[R any](querySQL string, opts ...OptionFunc) ([]*R, *gorm.DB) { resultDb := getDb(opts...) var results []*R - resultDb = resultDb.Raw(querySql).Scan(&results) + resultDb = resultDb.Raw(querySQL).Scan(&results) return results, resultDb } -// SelectOneBySql 根据原始的SQL语句,取一个 -func SelectOneBySql[R any](countSql string, opts ...OptionFunc) (R, *gorm.DB) { +// SelectOneBySQL 根据原始的SQL语句,取一个 +func SelectOneBySQL[R any](countSQL string, opts ...OptionFunc) (R, *gorm.DB) { resultDb := getDb(opts...) var result R - resultDb = resultDb.Raw(countSql).Scan(&result) + resultDb = resultDb.Raw(countSQL).Scan(&result) return result, resultDb } -// ExcSql 按任意SQL执行,返回影响的行 -func ExcSql(querySql string, opts ...OptionFunc) *gorm.DB { +// ExcSQL 按任意SQL执行,返回影响的行 +func ExcSQL(querySQL string, opts ...OptionFunc) *gorm.DB { resultDb := getDb(opts...) - resultDb = resultDb.Exec(querySql) + resultDb = resultDb.Exec(querySQL) return resultDb } @@ -460,7 +468,7 @@ func buildCondition[T any](q *QueryCond[T], opts ...OptionFunc) *gorm.DB { expressions := q.queryExpressions if len(expressions) > 0 { var sqlBuilder strings.Builder - q.queryArgs = buildSqlAndArgs[T](expressions, &sqlBuilder, q.queryArgs) + q.queryArgs = buildSQLAndArgs[T](expressions, &sqlBuilder, q.queryArgs) resultDb.Where(sqlBuilder.String(), q.queryArgs...) } @@ -487,21 +495,21 @@ func buildCondition[T any](q *QueryCond[T], opts ...OptionFunc) *gorm.DB { return resultDb } -func buildSqlAndArgs[T any](expressions []any, sqlBuilder *strings.Builder, queryArgs []any) []any { +func buildSQLAndArgs[T any](expressions []any, sqlBuilder *strings.Builder, queryArgs []any) []any { for _, v := range expressions { // 判断是否是columnValue类型 switch segment := v.(type) { case *columnPointer: - sqlBuilder.WriteString(segment.getSqlSegment() + " ") + sqlBuilder.WriteString(segment.getSQLSegment() + " ") //nolint: errcheck case *sqlKeyword: - sqlBuilder.WriteString(segment.getSqlSegment() + " ") + sqlBuilder.WriteString(segment.getSQLSegment() + " ") //nolint: errcheck case *columnValue: if segment.value == constants.And { - sqlBuilder.WriteString(segment.value.(string) + " ") + sqlBuilder.WriteString(segment.value.(string) + " ") //nolint: errcheck continue } if segment.value != nil { // 条件可以给空字符串 - sqlBuilder.WriteString("? ") //nolint + sqlBuilder.WriteString("? ") //nolint: errcheck queryArgs = append(queryArgs, segment.value) } case *QueryCond[T]: @@ -509,10 +517,10 @@ func buildSqlAndArgs[T any](expressions []any, sqlBuilder *strings.Builder, quer if len(segment.queryExpressions) == 0 { continue } - sqlBuilder.WriteString(constants.LeftBracket + " ") + sqlBuilder.WriteString(constants.LeftBracket + " ") //nolint: errcheck // 递归处理条件 - queryArgs = buildSqlAndArgs[T](segment.queryExpressions, sqlBuilder, queryArgs) - sqlBuilder.WriteString(constants.RightBracket + " ") + queryArgs = buildSQLAndArgs[T](segment.queryExpressions, sqlBuilder, queryArgs) + sqlBuilder.WriteString(constants.RightBracket + " ") //nolint: errcheck } } return queryArgs diff --git a/gplus/query.go b/gplus/query.go index 796baf0..f0d222e 100644 --- a/gplus/query.go +++ b/gplus/query.go @@ -42,7 +42,7 @@ type QueryCond[T any] struct { columnTypeMap map[string]reflect.Type } -func (q *QueryCond[T]) getSqlSegment() string { +func (q *QueryCond[T]) getSQLSegment() string { return "" } @@ -222,9 +222,9 @@ func (q *QueryCond[T]) Group(columns ...any) *QueryCond[T] { for _, v := range columns { columnName := getColumnName(v) if q.groupBuilder.Len() > 0 { - q.groupBuilder.WriteString(constants.Comma) + q.groupBuilder.WriteString(constants.Comma) //nolint: errcheck } - q.groupBuilder.WriteString(columnName) + q.groupBuilder.WriteString(columnName) //nolint: errcheck } return q } @@ -651,7 +651,7 @@ func (q *QueryCond[T]) OrInCond(cond bool, column any, val any) *QueryCond[T] { return q } -func (q *QueryCond[T]) addExpression(sqlSegments ...SqlSegment) { +func (q *QueryCond[T]) addExpression(sqlSegments ...SQLSegment) { if len(sqlSegments) == 1 { q.handleSingle(sqlSegments[0]) return @@ -680,7 +680,7 @@ func (q *QueryCond[T]) addAndCondIfNeed() { } } -func (q *QueryCond[T]) handleSingle(sqlSegment SqlSegment) { +func (q *QueryCond[T]) handleSingle(sqlSegment SQLSegment) { // 如何是第一次设置,则不需要添加and(),or(),防止用户首次设置条件错误 if len(q.queryExpressions) == 0 { return @@ -696,7 +696,7 @@ func (q *QueryCond[T]) handleSingle(sqlSegment SqlSegment) { } } -func (q *QueryCond[T]) handelRepeat(sqlSegment SqlSegment) bool { +func (q *QueryCond[T]) handelRepeat(sqlSegment SQLSegment) bool { currentKeyword, isCurrentKeyword := sqlSegment.(*sqlKeyword) lastKeyword, isLastKeyword := q.last.(*sqlKeyword) if isCurrentKeyword && isLastKeyword { @@ -725,8 +725,8 @@ func isLastNotAndOr(lastKeyword *sqlKeyword, isKeyword bool, expressions []any) return isKeyword && lastKeyword.keyword != constants.And && lastKeyword.keyword != constants.Or && len(expressions) > 0 } -func (q *QueryCond[T]) buildSqlSegment(column any, condType string, values ...any) []SqlSegment { - var sqlSegments []SqlSegment +func (q *QueryCond[T]) buildSqlSegment(column any, condType string, values ...any) []SQLSegment { + var sqlSegments []SQLSegment sqlSegments = append(sqlSegments, &columnPointer{column: column}, &sqlKeyword{keyword: condType}) for _, val := range values { cv := columnValue{value: val} @@ -738,15 +738,15 @@ func (q *QueryCond[T]) buildSqlSegment(column any, condType string, values ...an func (q *QueryCond[T]) buildOrder(orderType string, columns ...string) { for _, v := range columns { if q.orderBuilder.Len() > 0 { - q.orderBuilder.WriteString(constants.Comma) + q.orderBuilder.WriteString(constants.Comma) //nolint } - q.orderBuilder.WriteString(v) - q.orderBuilder.WriteString(" ") + q.orderBuilder.WriteString(v) //nolint + q.orderBuilder.WriteString(" ") //nolint q.orderBuilder.WriteString(orderType) } } -// 执行增加AND条件 +// AddAndStrCond 执行增加AND条件 func (q *QueryCond[T]) AddAndStrCond(cond string) *QueryCond[T] { if len(q.queryExpressions) > 0 { sk := sqlKeyword{keyword: constants.And} @@ -758,7 +758,7 @@ func (q *QueryCond[T]) AddAndStrCond(cond string) *QueryCond[T] { return q } -// 执行增加OR条件 +// AddOrStrCond 执行增加OR条件 func (q *QueryCond[T]) AddOrStrCond(cond string) *QueryCond[T] { if len(q.queryExpressions) > 0 { sk := sqlKeyword{keyword: constants.Or} @@ -770,7 +770,7 @@ func (q *QueryCond[T]) AddOrStrCond(cond string) *QueryCond[T] { return q } -// 根据条件,执行方法 +// Case 根据条件,执行方法 func (q *QueryCond[T]) Case(isTrue bool, handleFunc func()) *QueryCond[T] { if isTrue { handleFunc() @@ -778,7 +778,7 @@ func (q *QueryCond[T]) Case(isTrue bool, handleFunc func()) *QueryCond[T] { return q } -// 重置查询条件 +// Reset 重置查询条件 func (q *QueryCond[T]) Reset() *QueryCond[T] { q.selectColumns = q.selectColumns[:0] q.omitColumns = q.omitColumns[:0] diff --git a/gplus/segment.go b/gplus/segment.go index 46062db..38d24dd 100644 --- a/gplus/segment.go +++ b/gplus/segment.go @@ -17,15 +17,15 @@ package gplus -type SqlSegment interface { - getSqlSegment() string +type SQLSegment interface { + getSQLSegment() string } type columnPointer struct { column any } -func (cp *columnPointer) getSqlSegment() string { +func (cp *columnPointer) getSQLSegment() string { return getColumnName(cp.column) } @@ -33,7 +33,7 @@ type sqlKeyword struct { keyword string } -func (sk *sqlKeyword) getSqlSegment() string { +func (sk *sqlKeyword) getSQLSegment() string { return sk.keyword } @@ -41,6 +41,6 @@ type columnValue struct { value any } -func (cv *columnValue) getSqlSegment() string { +func (cv *columnValue) getSQLSegment() string { return "" } diff --git a/gplus/tool.go b/gplus/tool.go index 26c1468..51daeb1 100644 --- a/gplus/tool.go +++ b/gplus/tool.go @@ -24,8 +24,11 @@ import ( "strconv" "strings" "sync" + + "github.com/aixj1984/gorm-plus/constants" ) +// Condition 条件结构体 type Condition struct { Group string ColumnName string @@ -57,6 +60,7 @@ var ( } ) +// BuildQuery 编译查询 func BuildQuery[T any](queryParams url.Values) *QueryCond[T] { columnCondMap, conditionMap, gcond := parseParams(queryParams) @@ -93,21 +97,21 @@ func parseParams(queryParams url.Values) (map[string][]*Condition, map[string]st conditionMap := make(map[string]string) for key, values := range queryParams { switch key { - case "q": + case "q": //nolint columnCondMap = buildColumnCondMap(values) - case "sort": + case "sort": //nolint if len(values) > 0 { conditionMap["sort"] = values[len(values)-1] } - case "select": + case "select": //nolint if len(values) > 0 { conditionMap["select"] = values[len(values)-1] } - case "omit": + case "omit": //nolint if len(values) > 0 { conditionMap["omit"] = values[len(values)-1] } - case "gcond": + case "gcond": //nolint gcond = values[0] } } @@ -327,10 +331,12 @@ func notLikeRight(query *QueryCond[any], name string, value any) { query.NotLikeRight(name, convert(query.columnTypeMap, name, value)) } +// LikeLeft 左模糊 LIKE '%值' func LikeLeft(query *QueryCond[any], name string, value any) { query.LikeLeft(name, convert(query.columnTypeMap, name, value)) } +// LikeRight 右模糊 LIKE '值%' func LikeRight(query *QueryCond[any], name string, value any) { query.LikeRight(name, convert(query.columnTypeMap, name, value)) } @@ -376,7 +382,7 @@ func like(query *QueryCond[any], name string, value any) { } func ne(query *QueryCond[any], name string, value any) { - if strings.ToLower(fmt.Sprintf("%s", value)) == "null" { + if strings.ToLower(fmt.Sprintf("%s", value)) == constants.NullString { query.IsNotNull(name) } else { query.Ne(name, convert(query.columnTypeMap, name, value)) @@ -392,7 +398,7 @@ func le(query *QueryCond[any], name string, value any) { } func eq(query *QueryCond[any], name string, value any) { - if strings.ToLower(fmt.Sprintf("%s", value)) == "null" { + if strings.ToLower(fmt.Sprintf("%s", value)) == constants.NullString { query.IsNull(name) } else { query.Eq(name, convert(query.columnTypeMap, name, value)) diff --git a/tests/dao_test.go b/tests/dao_test.go index 0e79f6e..54db662 100644 --- a/tests/dao_test.go +++ b/tests/dao_test.go @@ -694,7 +694,7 @@ func TestBySql(t *testing.T) { Num int } - records, db := gplus.SelectListBySql[UserPlus]("select * , 1 as num from Users") + records, db := gplus.SelectListBySQL[UserPlus]("select * , 1 as num from Users") if db.Error != nil { t.Errorf("errors happened when SelectCount : %v", db.Error) } @@ -709,7 +709,7 @@ func TestBySql(t *testing.T) { t.Errorf("count expects: %v, got %v", len(records), 0) } - db = gplus.ExcSql("delete from Users") + db = gplus.ExcSQL("delete from Users") if db.Error != nil { t.Errorf("errors happened when SelectCount : %v", db.Error) diff --git a/tests/delete_test.go b/tests/delete_test.go index ffb4a9c..0cf2e48 100644 --- a/tests/delete_test.go +++ b/tests/delete_test.go @@ -214,7 +214,7 @@ func checkDeleteSql(t *testing.T, expect string) *gorm.DB { sessionDb := gormDb.Session(&gorm.Session{DryRun: true}) callBack := sessionDb.Callback().Delete().Before("gorm:DELETE") callBack.Register("print_sql", func(db *gorm.DB) { - sql := buildSql(db) + sql := buildSQL(db) sql = strings.TrimSpace(sql) if sql != expect { t.Errorf("errors happened when delete expect: %v, got %v", expect, sql) diff --git a/tests/insert_test.go b/tests/insert_test.go index f484ca3..0b3c4e1 100644 --- a/tests/insert_test.go +++ b/tests/insert_test.go @@ -74,7 +74,7 @@ func checkInsertSql(t *testing.T, expect string) *gorm.DB { sessionDb := gormDb.Session(&gorm.Session{DryRun: true}) callback := sessionDb.Callback().Create().Before("gorm:insert") callback.Register("print_sql", func(db *gorm.DB) { - sql := buildSql(db) + sql := buildSQL(db) sql = strings.TrimSpace(sql) if sql != expect { t.Errorf("errors happened when insert expect: %v, got %v", expect, sql) diff --git a/tests/select_test.go b/tests/select_test.go index 8679b9d..9184ddd 100644 --- a/tests/select_test.go +++ b/tests/select_test.go @@ -305,7 +305,7 @@ func checkSelectSql(t *testing.T, expect string) *gorm.DB { sessionDb := gormDb.Session(&gorm.Session{DryRun: true}) callback := sessionDb.Callback().Query().After("gorm:query") callback.Register("print_sql", func(db *gorm.DB) { - sql := buildSql(db) + sql := buildSQL(db) sql = strings.TrimSpace(sql) if sql != expect { t.Errorf("errors happened when select expect: %v, got %v", expect, sql) diff --git a/tests/update_test.go b/tests/update_test.go index f2a02ca..ac04263 100644 --- a/tests/update_test.go +++ b/tests/update_test.go @@ -137,7 +137,7 @@ func checkUpdateSql(t *testing.T, expect string) *gorm.DB { sessionDb := gormDb.Session(&gorm.Session{DryRun: true}) callback := sessionDb.Callback().Update().After("gorm:update") callback.Register("print_sql", func(db *gorm.DB) { - sql := buildSql(db) + sql := buildSQL(db) sql = strings.TrimSpace(sql) if sql != expect { t.Errorf("errors happened when update expect: %v, got %v", expect, sql) diff --git a/tests/utils.go b/tests/utils.go index e8dd6f3..e001d0f 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -31,6 +31,7 @@ import ( "gorm.io/gorm/utils" ) +// AssertObjEqual 断言等 func AssertObjEqual(t *testing.T, r, e interface{}, names ...string) { for _, name := range names { got := reflect.Indirect(reflect.ValueOf(r)).FieldByName(name).Interface() @@ -41,7 +42,8 @@ func AssertObjEqual(t *testing.T, r, e interface{}, names ...string) { } } -func AssertEqual(t *testing.T, got, expect interface{}) { +// AssertEqual 断言等 +func AssertEqual(t *testing.T, got, expect interface{}) { //nolint: funlen,gocyclo if !reflect.DeepEqual(got, expect) { isEqual := func() { if curTime, ok := got.(time.Time); ok { @@ -136,12 +138,13 @@ func AssertEqual(t *testing.T, got, expect interface{}) { } } +// Now 获取当前时间 func Now() *time.Time { now := time.Now() return &now } -func buildSql(db *gorm.DB) string { +func buildSQL(db *gorm.DB) string { sql := db.Statement.SQL.String() for _, value := range db.Statement.Vars { sql = strings.Replace(sql, "?", convert(value), 1)