use golang ci lint v1 (#2551)
Reviewed-on: https://gitea.com/xorm/xorm/pulls/2551
This commit is contained in:
@@ -39,3 +39,4 @@ tests/*.sql
|
||||
tests/test_sqlite*
|
||||
cover.out
|
||||
cover.html
|
||||
bin/
|
||||
+27
-197
@@ -1,198 +1,28 @@
|
||||
version: "2"
|
||||
output:
|
||||
sort-order:
|
||||
- file
|
||||
linters:
|
||||
default: none
|
||||
enable:
|
||||
- bidichk
|
||||
- bodyclose
|
||||
- depguard
|
||||
- dupl
|
||||
- errcheck
|
||||
- forbidigo
|
||||
- gocheckcompilerdirectives
|
||||
- gocritic
|
||||
- govet
|
||||
- ineffassign
|
||||
- mirror
|
||||
- modernize
|
||||
- nakedret
|
||||
- nolintlint
|
||||
- perfsprint
|
||||
- revive
|
||||
- staticcheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- usestdlibvars
|
||||
- usetesting
|
||||
- wastedassign
|
||||
settings:
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: github.com/unknwon/com
|
||||
desc: use gitea's util and replacements
|
||||
- pkg: io/ioutil
|
||||
desc: use os or io instead
|
||||
- pkg: golang.org/x/exp
|
||||
desc: it's experimental and unreliable
|
||||
- pkg: gopkg.in/ini.v1
|
||||
desc: do not use the ini package, use gitea's config system instead
|
||||
- pkg: github.com/pkg/errors
|
||||
desc: use builtin errors package instead
|
||||
- pkg: github.com/go-ap/errors
|
||||
desc: use builtin errors package instead
|
||||
nolintlint:
|
||||
allow-unused: false
|
||||
require-explanation: true
|
||||
require-specific: true
|
||||
gocritic:
|
||||
enabled-checks:
|
||||
- equalFold
|
||||
disabled-checks:
|
||||
- ifElseChain
|
||||
- singleCaseSwitch # Every time this occurred in the code, there was no other way.
|
||||
- deprecatedComment # conflicts with go-swagger comments
|
||||
revive:
|
||||
severity: error
|
||||
rules:
|
||||
- name: atomic
|
||||
- name: bare-return
|
||||
- name: blank-imports
|
||||
- name: constant-logical-expr
|
||||
- name: context-as-argument
|
||||
disabled: true
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: duplicated-imports
|
||||
- name: empty-lines
|
||||
- name: error-naming
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: errorf
|
||||
- name: exported
|
||||
disabled: true
|
||||
- name: identical-branches
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: indent-error-flow
|
||||
- name: modifies-value-receiver
|
||||
- name: package-comments
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: redefines-builtin-id
|
||||
- name: string-of-int
|
||||
- name: superfluous-else
|
||||
- name: time-naming
|
||||
- name: unconditional-recursion
|
||||
- name: unexported-return
|
||||
disabled: true
|
||||
- name: unreachable-code
|
||||
- name: var-declaration
|
||||
- name: var-naming
|
||||
disabled: true
|
||||
arguments:
|
||||
- [] # AllowList - do not remove as args for the rule are positional and won't work without lists first
|
||||
- [] # DenyList
|
||||
- - skip-package-name-checks: true # supress errors from underscore in migration packages
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- -ST1003
|
||||
- -ST1005
|
||||
- -QF1001
|
||||
- -QF1006
|
||||
- -QF1008
|
||||
testifylint:
|
||||
disable:
|
||||
- go-require
|
||||
- require-error
|
||||
usetesting:
|
||||
os-temp-dir: true
|
||||
perfsprint:
|
||||
concat-loop: false
|
||||
govet:
|
||||
enable:
|
||||
- nilness
|
||||
- unusedwrite
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- common-false-positives
|
||||
- legacy
|
||||
- std-error-handling
|
||||
rules:
|
||||
- linters:
|
||||
- dupl
|
||||
- errcheck
|
||||
- gocyclo
|
||||
- gosec
|
||||
- staticcheck
|
||||
- unparam
|
||||
path: _test\.go
|
||||
- linters:
|
||||
- dupl
|
||||
- errcheck
|
||||
- gocyclo
|
||||
- gosec
|
||||
path: models/migrations/v
|
||||
- linters:
|
||||
- forbidigo
|
||||
path: cmd
|
||||
- linters:
|
||||
- dupl
|
||||
text: (?i)webhook
|
||||
- linters:
|
||||
- dupl
|
||||
path: dialects/(dameng|gbase8s|oracle)\.go
|
||||
- linters:
|
||||
- gocritic
|
||||
text: (?i)`ID' should not be capitalized
|
||||
- linters:
|
||||
- deadcode
|
||||
- unused
|
||||
text: (?i)swagger
|
||||
- linters:
|
||||
- staticcheck
|
||||
text: (?i)argument x is overwritten before first use
|
||||
- linters:
|
||||
- gocritic
|
||||
text: '(?i)commentFormatting: put a space between `//` and comment text'
|
||||
- linters:
|
||||
- gocritic
|
||||
text: '(?i)exitAfterDefer:'
|
||||
paths:
|
||||
- node_modules
|
||||
- .venv
|
||||
- public
|
||||
- web_src
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
issues:
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
formatters:
|
||||
enable:
|
||||
- gofmt
|
||||
- gofumpt
|
||||
settings:
|
||||
gofumpt:
|
||||
extra-rules: true
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- node_modules
|
||||
- .venv
|
||||
- public
|
||||
- web_src
|
||||
- third_party$
|
||||
- builtin$
|
||||
- examples$
|
||||
|
||||
run:
|
||||
timeout: 10m
|
||||
go: "1.20"
|
||||
timeout: 5m
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- govet
|
||||
- errcheck
|
||||
- staticcheck
|
||||
- gosimple
|
||||
- ineffassign
|
||||
- typecheck
|
||||
- gofmt
|
||||
- goimports
|
||||
- misspell
|
||||
- unconvert
|
||||
- gocritic
|
||||
|
||||
disable:
|
||||
- depguard
|
||||
- wsl
|
||||
- funlen
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- errcheck
|
||||
@@ -11,7 +11,7 @@ GOFILES := $(wildcard *.go)
|
||||
GOFILES += $(shell find $(GO_DIRS) -name "*.go" -type f)
|
||||
INTEGRATION_PACKAGES := xorm.io/xorm/tests
|
||||
PACKAGES ?= $(filter-out $(INTEGRATION_PACKAGES),$(shell $(GO) list ./...))
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.8.0
|
||||
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2
|
||||
|
||||
TEST_COCKROACH_HOST ?= cockroach:26257
|
||||
TEST_COCKROACH_SCHEMA ?=
|
||||
@@ -111,9 +111,18 @@ help:
|
||||
@echo " - test-tidb run integration tests for tidb"
|
||||
@echo " - vet examines Go source code and reports suspicious constructs"
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
$(GO) run $(GOLANGCI_LINT_PACKAGE) run
|
||||
GOLANGCI_LINT_VERSION ?= v1.55.2
|
||||
GOLANGCI_LINT ?= $(PWD)/bin/golangci-lint
|
||||
GOLANGCI_LINT_GOTOOLCHAIN ?= go1.20.14
|
||||
|
||||
.PHONY: lint lint-install
|
||||
lint: lint-install
|
||||
GOTOOLCHAIN=$(GOLANGCI_LINT_GOTOOLCHAIN) $(GOLANGCI_LINT) run
|
||||
|
||||
lint-install:
|
||||
test -x $(GOLANGCI_LINT) || \
|
||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | \
|
||||
sh -s -- -b $(PWD)/bin $(GOLANGCI_LINT_VERSION)
|
||||
|
||||
.PHONY: test
|
||||
test: go-check
|
||||
|
||||
@@ -241,8 +241,7 @@ func Assign(dest, src any, originalLocation, convertedLocation *time.Location) e
|
||||
return nil
|
||||
}
|
||||
case *sql.NullBool:
|
||||
switch d := dest.(type) {
|
||||
case *bool:
|
||||
if d, ok := dest.(*bool); ok {
|
||||
if s.Valid {
|
||||
*d = s.Bool
|
||||
}
|
||||
@@ -280,16 +279,14 @@ func Assign(dest, src any, originalLocation, convertedLocation *time.Location) e
|
||||
return nil
|
||||
}
|
||||
case *NullUint64:
|
||||
switch d := dest.(type) {
|
||||
case *uint64:
|
||||
if d, ok := dest.(*uint64); ok {
|
||||
if s.Valid {
|
||||
*d = s.Uint64
|
||||
}
|
||||
return nil
|
||||
}
|
||||
case *sql.RawBytes:
|
||||
switch d := dest.(type) {
|
||||
case Conversion:
|
||||
if d, ok := dest.(Conversion); ok {
|
||||
return d.FromDB(*s)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ func AsFloat64(src any) (float64, error) {
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return float64(rv.Uint()), nil
|
||||
case reflect.Float64, reflect.Float32:
|
||||
return float64(rv.Float()), nil
|
||||
return rv.Float(), nil
|
||||
case reflect.String:
|
||||
return strconv.ParseFloat(rv.String(), 64)
|
||||
}
|
||||
|
||||
+8
-7
@@ -17,7 +17,8 @@ import (
|
||||
// String2Time converts a string to time with original location
|
||||
// be aware for time strings (HH:mm:ss) returns zero year (LMT) for converted location
|
||||
func String2Time(s string, originalLocation, convertedLocation *time.Location) (*time.Time, error) {
|
||||
if len(s) == 19 {
|
||||
switch {
|
||||
case len(s) == 19:
|
||||
if s == utils.ZeroTime0 || s == utils.ZeroTime1 {
|
||||
return &time.Time{}, nil
|
||||
}
|
||||
@@ -27,7 +28,7 @@ func String2Time(s string, originalLocation, convertedLocation *time.Location) (
|
||||
}
|
||||
dt = dt.In(convertedLocation)
|
||||
return &dt, nil
|
||||
} else if len(s) == 20 && s[10] == 'T' && s[19] == 'Z' {
|
||||
case len(s) == 20 && s[10] == 'T' && s[19] == 'Z':
|
||||
if strings.HasPrefix(s, "0000-00-00T00:00:00") || strings.HasPrefix(s, "0001-01-01T00:00:00") {
|
||||
return &time.Time{}, nil
|
||||
}
|
||||
@@ -37,7 +38,7 @@ func String2Time(s string, originalLocation, convertedLocation *time.Location) (
|
||||
}
|
||||
dt = dt.In(convertedLocation)
|
||||
return &dt, nil
|
||||
} else if len(s) == 25 && s[10] == 'T' && s[19] == '+' && s[22] == ':' {
|
||||
case len(s) == 25 && s[10] == 'T' && s[19] == '+' && s[22] == ':':
|
||||
if strings.HasPrefix(s, "0000-00-00T00:00:00") || strings.HasPrefix(s, "0001-01-01T00:00:00") {
|
||||
return &time.Time{}, nil
|
||||
}
|
||||
@@ -47,7 +48,7 @@ func String2Time(s string, originalLocation, convertedLocation *time.Location) (
|
||||
}
|
||||
dt = dt.In(convertedLocation)
|
||||
return &dt, nil
|
||||
} else if len(s) >= 21 && s[10] == 'T' && s[19] == '.' {
|
||||
case len(s) >= 21 && s[10] == 'T' && s[19] == '.':
|
||||
if strings.HasPrefix(s, "0000-00-00T00:00:00."+strings.Repeat("0", len(s)-20)) ||
|
||||
strings.HasPrefix(s, "0001-01-01T00:00:00."+strings.Repeat("0", len(s)-20)) {
|
||||
return &time.Time{}, nil
|
||||
@@ -58,7 +59,7 @@ func String2Time(s string, originalLocation, convertedLocation *time.Location) (
|
||||
}
|
||||
dt = dt.In(convertedLocation)
|
||||
return &dt, nil
|
||||
} else if len(s) >= 21 && s[19] == '.' {
|
||||
case len(s) >= 21 && s[19] == '.':
|
||||
if strings.HasPrefix(s, "0000-00-00T00:00:00."+strings.Repeat("0", len(s)-20)) ||
|
||||
strings.HasPrefix(s, "0001-01-01T00:00:00."+strings.Repeat("0", len(s)-20)) {
|
||||
return &time.Time{}, nil
|
||||
@@ -70,7 +71,7 @@ func String2Time(s string, originalLocation, convertedLocation *time.Location) (
|
||||
}
|
||||
dt = dt.In(convertedLocation)
|
||||
return &dt, nil
|
||||
} else if len(s) == 10 && s[4] == '-' {
|
||||
case len(s) == 10 && s[4] == '-':
|
||||
if s == "0000-00-00" || s == "0001-01-01" {
|
||||
return &time.Time{}, nil
|
||||
}
|
||||
@@ -80,7 +81,7 @@ func String2Time(s string, originalLocation, convertedLocation *time.Location) (
|
||||
}
|
||||
dt = dt.In(convertedLocation)
|
||||
return &dt, nil
|
||||
} else if len(s) == 8 && s[2] == ':' && s[5] == ':' {
|
||||
case len(s) == 8 && s[2] == ':' && s[5] == ':':
|
||||
dt, err := time.ParseInLocation("15:04:05", s, originalLocation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+20
-18
@@ -37,38 +37,39 @@ func postgresSeqFilterConvertQuestionMark(sql, prefix string, start int) string
|
||||
buf.WriteString(fmt.Sprintf("%s%v", prefix, index))
|
||||
index++
|
||||
} else {
|
||||
if isMaybeJsonbQuestion && c == '?' {
|
||||
switch {
|
||||
case isMaybeJsonbQuestion && c == '?':
|
||||
isMaybeJsonbQuestion = false
|
||||
} else if isMaybeLineComment {
|
||||
case isMaybeLineComment:
|
||||
if c == '-' {
|
||||
isLineComment = true
|
||||
}
|
||||
isMaybeLineComment = false
|
||||
} else if isMaybeComment {
|
||||
case isMaybeComment:
|
||||
if c == '*' {
|
||||
isComment = true
|
||||
}
|
||||
isMaybeComment = false
|
||||
} else if isMaybeCommentEnd {
|
||||
case isMaybeCommentEnd:
|
||||
if c == '/' {
|
||||
isComment = false
|
||||
}
|
||||
isMaybeCommentEnd = false
|
||||
} else if isLineComment {
|
||||
case isLineComment:
|
||||
if c == '\n' {
|
||||
isLineComment = false
|
||||
}
|
||||
} else if isComment {
|
||||
case isComment:
|
||||
if c == '*' {
|
||||
isMaybeCommentEnd = true
|
||||
}
|
||||
} else if !beginSingleQuote && c == '-' {
|
||||
case !beginSingleQuote && c == '-':
|
||||
isMaybeLineComment = true
|
||||
} else if !beginSingleQuote && c == '/' {
|
||||
case !beginSingleQuote && c == '/':
|
||||
isMaybeComment = true
|
||||
} else if !beginSingleQuote && c == ' ' && i >= 7 && strings.TrimSpace(sql[i-7:i]) == "::jsonb" {
|
||||
case !beginSingleQuote && c == ' ' && i >= 7 && strings.TrimSpace(sql[i-7:i]) == "::jsonb":
|
||||
isMaybeJsonbQuestion = true
|
||||
} else if c == '\'' {
|
||||
case c == '\'':
|
||||
beginSingleQuote = !beginSingleQuote
|
||||
}
|
||||
buf.WriteRune(c)
|
||||
@@ -103,34 +104,35 @@ func oracleSeqFilterConvertQuestionMark(sql, prefix string, start int) string {
|
||||
buf.WriteString(strconv.Itoa(index))
|
||||
index++
|
||||
} else {
|
||||
if isMaybeLineComment {
|
||||
switch {
|
||||
case isMaybeLineComment:
|
||||
if c == '-' {
|
||||
isLineComment = true
|
||||
}
|
||||
isMaybeLineComment = false
|
||||
} else if isMaybeComment {
|
||||
case isMaybeComment:
|
||||
if c == '*' {
|
||||
isComment = true
|
||||
}
|
||||
isMaybeComment = false
|
||||
} else if isMaybeCommentEnd {
|
||||
case isMaybeCommentEnd:
|
||||
if c == '/' {
|
||||
isComment = false
|
||||
}
|
||||
isMaybeCommentEnd = false
|
||||
} else if isLineComment {
|
||||
case isLineComment:
|
||||
if c == '\n' {
|
||||
isLineComment = false
|
||||
}
|
||||
} else if isComment {
|
||||
case isComment:
|
||||
if c == '*' {
|
||||
isMaybeCommentEnd = true
|
||||
}
|
||||
} else if !beginSingleQuote && c == '-' {
|
||||
case !beginSingleQuote && c == '-':
|
||||
isMaybeLineComment = true
|
||||
} else if !beginSingleQuote && c == '/' {
|
||||
case !beginSingleQuote && c == '/':
|
||||
isMaybeComment = true
|
||||
} else if c == '\'' {
|
||||
case c == '\'':
|
||||
beginSingleQuote = !beginSingleQuote
|
||||
}
|
||||
buf.WriteRune(c)
|
||||
|
||||
+4
-3
@@ -622,11 +622,12 @@ func (db *gbase8s) SQLType(c *schemas.Column) string {
|
||||
}
|
||||
hasLen1 := c.Length > 0
|
||||
hasLen2 := c.Length2 > 0
|
||||
if res == "BIGINT" || res == "INT" || res == "SMALLINT" {
|
||||
switch {
|
||||
case res == "BIGINT" || res == "INT" || res == "SMALLINT":
|
||||
// GBase 8s INT doesn't need length specification
|
||||
} else if hasLen2 {
|
||||
case hasLen2:
|
||||
res += "(" + strconv.FormatInt(c.Length, 10) + "," + strconv.FormatInt(c.Length2, 10) + ")"
|
||||
} else if hasLen1 {
|
||||
case hasLen1:
|
||||
res += "(" + strconv.FormatInt(c.Length, 10) + ")"
|
||||
}
|
||||
return res
|
||||
|
||||
+4
-3
@@ -469,7 +469,8 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
|
||||
var len1, len2 int64
|
||||
if len(cts) == 2 {
|
||||
idx := strings.Index(cts[1], ")")
|
||||
if colType == schemas.Enum && cts[1][0] == '\'' { // enum
|
||||
switch {
|
||||
case colType == schemas.Enum && cts[1][0] == '\'': // enum
|
||||
options := strings.Split(cts[1][0:idx], ",")
|
||||
col.EnumOptions = make(map[string]int)
|
||||
for k, v := range options {
|
||||
@@ -477,7 +478,7 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
|
||||
v = strings.Trim(v, "'")
|
||||
col.EnumOptions[v] = k
|
||||
}
|
||||
} else if colType == schemas.Set && cts[1][0] == '\'' {
|
||||
case colType == schemas.Set && cts[1][0] == '\'':
|
||||
options := strings.Split(cts[1][0:idx], ",")
|
||||
col.SetOptions = make(map[string]int)
|
||||
for k, v := range options {
|
||||
@@ -485,7 +486,7 @@ func (db *mysql) GetColumns(queryer core.Queryer, ctx context.Context, tableName
|
||||
v = strings.Trim(v, "'")
|
||||
col.SetOptions[v] = k
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
lens := strings.Split(cts[1][0:idx], ",")
|
||||
len1, err = strconv.ParseInt(strings.TrimSpace(lens[0]), 10, 64)
|
||||
if err != nil {
|
||||
|
||||
@@ -824,13 +824,14 @@ func (db *postgres) Version(ctx context.Context, queryer core.Queryer) (*schemas
|
||||
// Postgres: PostgreSQL 15.3, compiled by Visual C++ build 1914, 64-bit
|
||||
// KingbaseES V008R006C008B0014 on x64, compiled by Visual C++ build 1800, 64-bit
|
||||
// CockroachDB CCL v19.2.4 (x86_64-unknown-linux-gnu, built
|
||||
if strings.HasPrefix(version, "CockroachDB") {
|
||||
switch {
|
||||
case strings.HasPrefix(version, "CockroachDB"):
|
||||
versions := strings.Split(strings.TrimPrefix(version, "CockroachDB CCL "), " ")
|
||||
return &schemas.Version{
|
||||
Number: strings.TrimPrefix(versions[0], "v"),
|
||||
Edition: "CockroachDB",
|
||||
}, nil
|
||||
} else if strings.HasPrefix(version, "PostgreSQL") {
|
||||
case strings.HasPrefix(version, "PostgreSQL"):
|
||||
if strings.Contains(version, " on ") {
|
||||
versions := strings.Split(strings.TrimPrefix(version, "PostgreSQL "), " on ")
|
||||
return &schemas.Version{
|
||||
@@ -845,7 +846,7 @@ func (db *postgres) Version(ctx context.Context, queryer core.Queryer) (*schemas
|
||||
Level: versions[1],
|
||||
Edition: "PostgreSQL",
|
||||
}, nil
|
||||
} else if strings.HasPrefix(version, "KingbaseES") {
|
||||
case strings.HasPrefix(version, "KingbaseES"):
|
||||
if strings.Contains(version, " on ") {
|
||||
versions := strings.Split(strings.TrimPrefix(version, "KingbaseES "), " on ")
|
||||
return &schemas.Version{
|
||||
|
||||
@@ -16,10 +16,10 @@ func TestParsePostgres(t *testing.T) {
|
||||
{"postgres://auser:password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
{"postgresql://auser:password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
{"postg://auser:password@localhost:5432/db?sslmode=disable", "db", false},
|
||||
//{"postgres://auser:pass with space@localhost:5432/db?sslmode=disable", "db", true},
|
||||
//{"postgres:// auser : password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
// {"postgres://auser:pass with space@localhost:5432/db?sslmode=disable", "db", true},
|
||||
// {"postgres:// auser : password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
{"postgres://%20auser%20:pass%20with%20space@localhost:5432/db?sslmode=disable", "db", true},
|
||||
//{"postgres://auser:パスワード@localhost:5432/データベース?sslmode=disable", "データベース", true},
|
||||
// {"postgres://auser:パスワード@localhost:5432/データベース?sslmode=disable", "データベース", true},
|
||||
{"dbname=db sslmode=disable", "db", true},
|
||||
{"user=auser password=password dbname=db sslmode=disable", "db", true},
|
||||
{"user=auser password='pass word' dbname=db sslmode=disable", "db", true},
|
||||
@@ -52,10 +52,10 @@ func TestParsePgx(t *testing.T) {
|
||||
{"postgres://auser:password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
{"postgresql://auser:password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
{"postg://auser:password@localhost:5432/db?sslmode=disable", "db", false},
|
||||
//{"postgres://auser:pass with space@localhost:5432/db?sslmode=disable", "db", true},
|
||||
//{"postgres:// auser : password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
// {"postgres://auser:pass with space@localhost:5432/db?sslmode=disable", "db", true},
|
||||
// {"postgres:// auser : password@localhost:5432/db?sslmode=disable", "db", true},
|
||||
{"postgres://%20auser%20:pass%20with%20space@localhost:5432/db?sslmode=disable", "db", true},
|
||||
//{"postgres://auser:パスワード@localhost:5432/データベース?sslmode=disable", "データベース", true},
|
||||
// {"postgres://auser:パスワード@localhost:5432/データベース?sslmode=disable", "データベース", true},
|
||||
{"dbname=db sslmode=disable", "db", true},
|
||||
{"user=auser password=password dbname=db sslmode=disable", "db", true},
|
||||
{"", "db", false},
|
||||
|
||||
@@ -644,7 +644,8 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if table.Columns()[i].SQLType.IsBool() || stp.IsBool() || (dstDialect.URI().DBType == schemas.MSSQL && strings.EqualFold(stp.Name, schemas.Bit)) {
|
||||
switch {
|
||||
case table.Columns()[i].SQLType.IsBool() || stp.IsBool() || (dstDialect.URI().DBType == schemas.MSSQL && strings.EqualFold(stp.Name, schemas.Bit)):
|
||||
val, err := strconv.ParseBool(s.String)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -653,20 +654,20 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
if _, err = io.WriteString(w, formatBool(val, dstDialect)); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if stp.IsNumeric() {
|
||||
case stp.IsNumeric():
|
||||
if _, err = io.WriteString(w, s.String); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if sess.engine.dialect.URI().DBType == schemas.DAMENG && stp.IsTime() && len(s.String) == 25 {
|
||||
case sess.engine.dialect.URI().DBType == schemas.DAMENG && stp.IsTime() && len(s.String) == 25:
|
||||
r := strings.ReplaceAll(s.String[:19], "T", " ")
|
||||
if _, err = io.WriteString(w, "'"+r+"'"); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if len(s.String) == 0 {
|
||||
case len(s.String) == 0:
|
||||
if _, err := io.WriteString(w, "''"); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if dstDialect.URI().DBType == schemas.POSTGRES {
|
||||
case dstDialect.URI().DBType == schemas.POSTGRES:
|
||||
if dstTable.Columns()[i].SQLType.IsBlob() {
|
||||
// Postgres has the escape format and we should use that for bytea data
|
||||
if _, err := fmt.Fprintf(w, "'\\x%x'", s.String); err != nil {
|
||||
@@ -708,7 +709,7 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if dstDialect.URI().DBType == schemas.MYSQL {
|
||||
case dstDialect.URI().DBType == schemas.MYSQL:
|
||||
loc := controlCharactersRe.FindStringIndex(s.String)
|
||||
if loc == nil {
|
||||
if _, err := io.WriteString(w, "'"+strings.ReplaceAll(s.String, "'", "''")+"'"); err != nil {
|
||||
@@ -719,7 +720,7 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if dstDialect.URI().DBType == schemas.SQLITE {
|
||||
case dstDialect.URI().DBType == schemas.SQLITE:
|
||||
if dstTable.Columns()[i].SQLType.IsBlob() {
|
||||
// SQLite has its escape format
|
||||
if _, err := fmt.Fprintf(w, "X'%x'", s.String); err != nil {
|
||||
@@ -752,7 +753,7 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if dstDialect.URI().DBType == schemas.DAMENG || dstDialect.URI().DBType == schemas.ORACLE {
|
||||
case dstDialect.URI().DBType == schemas.DAMENG || dstDialect.URI().DBType == schemas.ORACLE:
|
||||
if dstTable.Columns()[i].SQLType.IsBlob() {
|
||||
// ORACLE/DAMENG uses HEXTORAW
|
||||
if _, err := fmt.Fprintf(w, "HEXTORAW('%x')", s.String); err != nil {
|
||||
@@ -765,7 +766,7 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if dstDialect.URI().DBType == schemas.MSSQL {
|
||||
case dstDialect.URI().DBType == schemas.MSSQL:
|
||||
if dstTable.Columns()[i].SQLType.IsBlob() {
|
||||
// MSSQL uses CONVERT(VARBINARY(MAX), '0xDEADBEEF', 1)
|
||||
if _, err := fmt.Fprintf(w, "CONVERT(VARBINARY(MAX), '0x%x', 1)", s.String); err != nil {
|
||||
@@ -776,7 +777,7 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else if sess.engine.dialect.URI().DBType == schemas.GBASE8S {
|
||||
case sess.engine.dialect.URI().DBType == schemas.GBASE8S:
|
||||
stp.Name = strings.Replace(stp.Name, "SQLT_", "", 1)
|
||||
if stp.IsTime() && len(s.String) == 20 { // "2025-06-10T07:55:31Z"
|
||||
t, err := time.Parse(time.RFC3339, s.String)
|
||||
@@ -792,7 +793,7 @@ func (engine *Engine) dumpTables(ctx context.Context, tables []*schemas.Table, w
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
if _, err = io.WriteString(w, "'"+strings.ReplaceAll(s.String, "'", "''")+"'"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -143,11 +143,12 @@ func (statement *Statement) GenCountSQL(beans ...any) (string, []any, error) {
|
||||
|
||||
selectSQL := statement.SelectStr
|
||||
if len(selectSQL) == 0 {
|
||||
if statement.IsDistinct {
|
||||
switch {
|
||||
case statement.IsDistinct:
|
||||
selectSQL = fmt.Sprintf("count(DISTINCT %s)", statement.ColumnStr())
|
||||
} else if statement.ColumnStr() != "" {
|
||||
case statement.ColumnStr() != "":
|
||||
selectSQL = fmt.Sprintf("count(%s)", statement.ColumnStr())
|
||||
} else {
|
||||
default:
|
||||
selectSQL = "count(*)"
|
||||
}
|
||||
}
|
||||
@@ -317,7 +318,8 @@ func (statement *Statement) GenExistSQL(bean ...any) (string, []any, error) {
|
||||
tableName = statement.quote(tableName)
|
||||
|
||||
buf := builder.NewWriter()
|
||||
if statement.dialect.URI().DBType == schemas.MSSQL {
|
||||
switch statement.dialect.URI().DBType {
|
||||
case schemas.MSSQL:
|
||||
if _, err := fmt.Fprintf(buf, "SELECT TOP 1 * FROM %s", tableName); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@@ -327,7 +329,7 @@ func (statement *Statement) GenExistSQL(bean ...any) (string, []any, error) {
|
||||
if err := statement.writeWhere(buf); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
} else if statement.dialect.URI().DBType == schemas.ORACLE {
|
||||
case schemas.ORACLE:
|
||||
if _, err := fmt.Fprintf(buf, "SELECT * FROM %s", tableName); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
@@ -348,7 +350,7 @@ func (statement *Statement) GenExistSQL(bean ...any) (string, []any, error) {
|
||||
if _, err := fmt.Fprintf(buf, "ROWNUM=1"); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
if _, err := fmt.Fprintf(buf, "SELECT 1 FROM %s", tableName); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
@@ -713,15 +713,16 @@ func (statement *Statement) CondDeleted(col *schemas.Column) builder.Cond {
|
||||
colName = statement.quote(prefix) + "." + statement.quote(col.Name)
|
||||
}
|
||||
var cond builder.Cond
|
||||
if col.SQLType.IsNumeric() {
|
||||
switch {
|
||||
case col.SQLType.IsNumeric():
|
||||
cond = builder.Eq{colName: 0}
|
||||
} else if col.SQLType.Name == schemas.TimeStamp || col.SQLType.Name == schemas.TimeStampz {
|
||||
case col.SQLType.Name == schemas.TimeStamp || col.SQLType.Name == schemas.TimeStampz:
|
||||
tmZone := statement.defaultTimeZone
|
||||
if col.TimeZone != nil {
|
||||
tmZone = col.TimeZone
|
||||
}
|
||||
cond = builder.Eq{colName: time.Unix(0, 0).In(tmZone).Format("2006-01-02 15:04:05.999999999")}
|
||||
} else {
|
||||
default:
|
||||
cond = builder.Eq{colName: utils.ZeroTime1}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,11 +52,12 @@ func (statement *Statement) ifAddColUpdate(col *schemas.Column, includeVersion,
|
||||
return false
|
||||
}
|
||||
|
||||
if statement.IncrColumns.IsColExist(col.Name) {
|
||||
switch {
|
||||
case statement.IncrColumns.IsColExist(col.Name):
|
||||
return false
|
||||
} else if statement.DecrColumns.IsColExist(col.Name) {
|
||||
case statement.DecrColumns.IsColExist(col.Name):
|
||||
return false
|
||||
} else if statement.ExprColumns.IsColExist(col.Name) {
|
||||
case statement.ExprColumns.IsColExist(col.Name):
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -268,33 +269,33 @@ func (statement *Statement) BuildUpdates(tableValue reflect.Value,
|
||||
}
|
||||
}
|
||||
|
||||
if col.SQLType.IsText() {
|
||||
switch {
|
||||
case col.SQLType.IsText():
|
||||
bytes, err := json.DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
val = string(bytes)
|
||||
} else if col.SQLType.IsBlob() {
|
||||
case col.SQLType.IsBlob():
|
||||
var bytes []byte
|
||||
var err error
|
||||
if fieldType.Kind() == reflect.Slice &&
|
||||
fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
switch {
|
||||
case fieldType.Kind() == reflect.Slice && fieldType.Elem().Kind() == reflect.Uint8:
|
||||
if fieldValue.Len() > 0 {
|
||||
val = fieldValue.Bytes()
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
} else if fieldType.Kind() == reflect.Array &&
|
||||
fieldType.Elem().Kind() == reflect.Uint8 {
|
||||
case fieldType.Kind() == reflect.Array && fieldType.Elem().Kind() == reflect.Uint8:
|
||||
val = fieldValue.Slice(0, 0).Interface()
|
||||
} else {
|
||||
default:
|
||||
bytes, err = json.DefaultJSONHandler.Marshal(fieldValue.Interface())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
val = bytes
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
continue
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -85,7 +85,8 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
|
||||
case reflect.String:
|
||||
return fieldValue.String(), nil
|
||||
case reflect.Struct:
|
||||
if fieldType.ConvertibleTo(schemas.TimeType) {
|
||||
switch {
|
||||
case fieldType.ConvertibleTo(schemas.TimeType):
|
||||
t := fieldValue.Convert(schemas.TimeType).Interface().(time.Time)
|
||||
tf, err := dialects.FormatColumnTime(statement.dialect, statement.defaultTimeZone, col, t)
|
||||
if val, ok := tf.(string); ok {
|
||||
@@ -101,13 +102,13 @@ func (statement *Statement) Value2Interface(col *schemas.Column, fieldValue refl
|
||||
return &DateTimeString{Layout: layout, Str: val}, err
|
||||
}
|
||||
return tf, err
|
||||
} else if fieldType.ConvertibleTo(nullFloatType) {
|
||||
case fieldType.ConvertibleTo(nullFloatType):
|
||||
t := fieldValue.Convert(nullFloatType).Interface().(sql.NullFloat64)
|
||||
if !t.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return t.Float64, nil
|
||||
} else if fieldType.ConvertibleTo(bigFloatType) {
|
||||
case fieldType.ConvertibleTo(bigFloatType):
|
||||
t := fieldValue.Convert(bigFloatType).Interface().(big.Float)
|
||||
return t.String(), nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package migrate
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -51,12 +50,12 @@ func TestMigration(t *testing.T) {
|
||||
|
||||
db, err := xorm.NewEngine("sqlite3", dbName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if err = db.Ping(); err != nil {
|
||||
log.Fatal(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m := New(db, DefaultOptions, migrations)
|
||||
@@ -91,11 +90,11 @@ func TestInitSchema(t *testing.T) {
|
||||
|
||||
db, err := xorm.NewEngine("sqlite3", dbName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
if err = db.Ping(); err != nil {
|
||||
log.Fatal(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
m := New(db, DefaultOptions, migrations)
|
||||
|
||||
+8
-6
@@ -31,17 +31,18 @@ func GetTableName(mapper Mapper, v reflect.Value) string {
|
||||
return v.Interface().(TableName).TableName()
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
switch {
|
||||
case v.Kind() == reflect.Ptr:
|
||||
v = v.Elem()
|
||||
if v.Type().Implements(tpTableName) {
|
||||
return v.Interface().(TableName).TableName()
|
||||
}
|
||||
} else if v.CanAddr() {
|
||||
case v.CanAddr():
|
||||
v1 := v.Addr()
|
||||
if v1.Type().Implements(tpTableName) {
|
||||
return v1.Interface().(TableName).TableName()
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
name, ok := tvCache.Load(v.Type())
|
||||
if ok {
|
||||
if name.(string) != "" {
|
||||
@@ -68,17 +69,18 @@ func GetTableComment(v reflect.Value) string {
|
||||
return v.Interface().(TableComment).TableComment()
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.Ptr {
|
||||
switch {
|
||||
case v.Kind() == reflect.Ptr:
|
||||
v = v.Elem()
|
||||
if v.Type().Implements(tpTableComment) {
|
||||
return v.Interface().(TableComment).TableComment()
|
||||
}
|
||||
} else if v.CanAddr() {
|
||||
case v.CanAddr():
|
||||
v1 := v.Addr()
|
||||
if v1.Type().Implements(tpTableComment) {
|
||||
return v1.Interface().(TableComment).TableComment()
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
comment, ok := tcCache.Load(v.Type())
|
||||
if ok {
|
||||
if comment.(string) != "" {
|
||||
|
||||
+8
-7
@@ -303,19 +303,20 @@ func Type2SQLType(t reflect.Type) (st SQLType) {
|
||||
case reflect.String:
|
||||
st = SQLType{Varchar, 255, 0}
|
||||
case reflect.Struct:
|
||||
if t.ConvertibleTo(TimeType) {
|
||||
switch {
|
||||
case t.ConvertibleTo(TimeType):
|
||||
st = SQLType{DateTime, 0, 0}
|
||||
} else if t.ConvertibleTo(NullFloat64Type) {
|
||||
case t.ConvertibleTo(NullFloat64Type):
|
||||
st = SQLType{Double, 0, 0}
|
||||
} else if t.ConvertibleTo(NullStringType) {
|
||||
case t.ConvertibleTo(NullStringType):
|
||||
st = SQLType{Varchar, 255, 0}
|
||||
} else if t.ConvertibleTo(NullInt32Type) {
|
||||
case t.ConvertibleTo(NullInt32Type):
|
||||
st = SQLType{Integer, 0, 0}
|
||||
} else if t.ConvertibleTo(NullInt64Type) {
|
||||
case t.ConvertibleTo(NullInt64Type):
|
||||
st = SQLType{BigInt, 0, 0}
|
||||
} else if t.ConvertibleTo(NullBoolType) {
|
||||
case t.ConvertibleTo(NullBoolType):
|
||||
st = SQLType{Boolean, 0, 0}
|
||||
} else {
|
||||
default:
|
||||
// TODO need to handle association struct
|
||||
st = SQLType{Text, 0, 0}
|
||||
}
|
||||
|
||||
+7
-4
@@ -51,17 +51,20 @@ func (session *Session) cacheDelete(table *schemas.Table, tableName, sqlStr stri
|
||||
var id int64
|
||||
var pk schemas.PK = make([]any, 0)
|
||||
for _, col := range pkColumns {
|
||||
if v, ok := data[col.Name]; !ok {
|
||||
v, ok := data[col.Name]
|
||||
if !ok {
|
||||
return errors.New("no id")
|
||||
} else if col.SQLType.IsText() {
|
||||
}
|
||||
switch {
|
||||
case col.SQLType.IsText():
|
||||
pk = append(pk, v)
|
||||
} else if col.SQLType.IsNumeric() {
|
||||
case col.SQLType.IsNumeric():
|
||||
id, err = strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pk = append(pk, id)
|
||||
} else {
|
||||
default:
|
||||
return errors.New("not supported primary key type")
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -95,7 +95,8 @@ func (session *Session) find(rowsSlicePtr any, condiBean ...any) error {
|
||||
|
||||
tp := tpStruct
|
||||
if session.statement.RefTable == nil {
|
||||
if sliceElementType.Kind() == reflect.Ptr {
|
||||
switch sliceElementType.Kind() {
|
||||
case reflect.Ptr:
|
||||
if sliceElementType.Elem().Kind() == reflect.Struct {
|
||||
pv := reflect.New(sliceElementType.Elem())
|
||||
if err := session.statement.SetRefValue(pv); err != nil {
|
||||
@@ -104,12 +105,12 @@ func (session *Session) find(rowsSlicePtr any, condiBean ...any) error {
|
||||
} else {
|
||||
tp = tpNonStruct
|
||||
}
|
||||
} else if sliceElementType.Kind() == reflect.Struct {
|
||||
case reflect.Struct:
|
||||
pv := reflect.New(sliceElementType)
|
||||
if err := session.statement.SetRefValue(pv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
tp = tpNonStruct
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -56,11 +56,12 @@ func (session *Session) get(beans ...any) (bool, error) {
|
||||
}
|
||||
|
||||
beanValue := reflect.ValueOf(beans[0])
|
||||
if beanValue.Kind() != reflect.Ptr {
|
||||
switch {
|
||||
case beanValue.Kind() != reflect.Ptr:
|
||||
return false, errors.New("needs a pointer to a value")
|
||||
} else if beanValue.Elem().Kind() == reflect.Ptr {
|
||||
case beanValue.Elem().Kind() == reflect.Ptr:
|
||||
return false, errors.New("a pointer to a pointer is not allowed")
|
||||
} else if beanValue.IsNil() {
|
||||
case beanValue.IsNil():
|
||||
return false, ErrObjectIsNil
|
||||
}
|
||||
|
||||
@@ -313,15 +314,16 @@ func (session *Session) cacheGet(bean any, sqlStr string, args ...any) (has bool
|
||||
|
||||
var pk schemas.PK = make([]any, len(table.PrimaryKeys))
|
||||
for i, col := range table.PKColumns() {
|
||||
if col.SQLType.IsText() {
|
||||
switch {
|
||||
case col.SQLType.IsText():
|
||||
pk[i] = res[i]
|
||||
} else if col.SQLType.IsNumeric() {
|
||||
case col.SQLType.IsNumeric():
|
||||
n, err := strconv.ParseInt(res[i], 10, 64)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pk[i] = n
|
||||
} else {
|
||||
default:
|
||||
return false, errors.New("unsupported")
|
||||
}
|
||||
}
|
||||
|
||||
+12
-9
@@ -152,7 +152,8 @@ func (session *Session) insertMultipleStruct(rowsSlicePtr any) (int64, error) {
|
||||
fieldValue = reflect.ValueOf(nilValue)
|
||||
}
|
||||
}
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime {
|
||||
switch {
|
||||
case (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime:
|
||||
val, t, err := session.engine.nowTime(col)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -164,14 +165,14 @@ func (session *Session) insertMultipleStruct(rowsSlicePtr any) (int64, error) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.statement.CheckVersion {
|
||||
case col.IsVersion && session.statement.CheckVersion:
|
||||
args = append(args, 1)
|
||||
colName := col.Name
|
||||
session.afterClosures = append(session.afterClosures, func(bean any) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnInt(bean, col, 1)
|
||||
})
|
||||
} else {
|
||||
default:
|
||||
arg, err := session.statement.Value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
@@ -465,11 +466,12 @@ func (session *Session) genInsertColumns(bean any) ([]string, []any, error) {
|
||||
if len(session.statement.ColumnMap) > 0 && !session.statement.ColumnMap.Contain(col.Name) {
|
||||
continue
|
||||
}
|
||||
if session.statement.IncrColumns.IsColExist(col.Name) {
|
||||
switch {
|
||||
case session.statement.IncrColumns.IsColExist(col.Name):
|
||||
continue
|
||||
} else if session.statement.DecrColumns.IsColExist(col.Name) {
|
||||
case session.statement.DecrColumns.IsColExist(col.Name):
|
||||
continue
|
||||
} else if session.statement.ExprColumns.IsColExist(col.Name) {
|
||||
case session.statement.ExprColumns.IsColExist(col.Name):
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -502,7 +504,8 @@ func (session *Session) genInsertColumns(bean any) ([]string, []any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
switch {
|
||||
case (col.IsCreated || col.IsUpdated) && session.statement.UseAutoTime: /*&& isZero(fieldValue.Interface())*/
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t, err := session.engine.nowTime(col)
|
||||
if err != nil {
|
||||
@@ -515,9 +518,9 @@ func (session *Session) genInsertColumns(bean any) ([]string, []any, error) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.statement.CheckVersion {
|
||||
case col.IsVersion && session.statement.CheckVersion:
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
default:
|
||||
arg, err := session.statement.Value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
|
||||
+12
-9
@@ -91,7 +91,8 @@ func (session *Session) Update(bean any, condiBean ...any) (int64, error) {
|
||||
var err error
|
||||
isMap := t.Kind() == reflect.Map
|
||||
isStruct := t.Kind() == reflect.Struct
|
||||
if isStruct {
|
||||
switch {
|
||||
case isStruct:
|
||||
if err := session.statement.SetRefBean(bean); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -109,7 +110,7 @@ func (session *Session) Update(bean any, condiBean ...any) (int64, error) {
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else if isMap {
|
||||
case isMap:
|
||||
colNames = make([]string, 0)
|
||||
args = make([]any, 0)
|
||||
bValue := reflect.Indirect(reflect.ValueOf(bean))
|
||||
@@ -118,7 +119,7 @@ func (session *Session) Update(bean any, condiBean ...any) (int64, error) {
|
||||
colNames = append(colNames, session.engine.Quote(v.String())+" = ?")
|
||||
args = append(args, bValue.MapIndex(v).Interface())
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
return 0, ErrParamsType
|
||||
}
|
||||
|
||||
@@ -270,11 +271,12 @@ func (session *Session) genUpdateColumns(bean any) ([]string, []any, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
if session.statement.IncrColumns.IsColExist(col.Name) {
|
||||
switch {
|
||||
case session.statement.IncrColumns.IsColExist(col.Name):
|
||||
continue
|
||||
} else if session.statement.DecrColumns.IsColExist(col.Name) {
|
||||
case session.statement.DecrColumns.IsColExist(col.Name):
|
||||
continue
|
||||
} else if session.statement.ExprColumns.IsColExist(col.Name) {
|
||||
case session.statement.ExprColumns.IsColExist(col.Name):
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -286,7 +288,8 @@ func (session *Session) genUpdateColumns(bean any) ([]string, []any, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if col.IsUpdated && session.statement.UseAutoTime /*&& isZero(fieldValue.Interface())*/ {
|
||||
switch {
|
||||
case col.IsUpdated && session.statement.UseAutoTime: /*&& isZero(fieldValue.Interface())*/
|
||||
// if time is non-empty, then set to auto time
|
||||
val, t, err := session.engine.nowTime(col)
|
||||
if err != nil {
|
||||
@@ -299,9 +302,9 @@ func (session *Session) genUpdateColumns(bean any) ([]string, []any, error) {
|
||||
col := table.GetColumn(colName)
|
||||
setColumnTime(bean, col, t)
|
||||
})
|
||||
} else if col.IsVersion && session.statement.CheckVersion {
|
||||
case col.IsVersion && session.statement.CheckVersion:
|
||||
args = append(args, 1)
|
||||
} else {
|
||||
default:
|
||||
arg, err := session.statement.Value2Interface(col, fieldValue)
|
||||
if err != nil {
|
||||
return colNames, args, err
|
||||
|
||||
@@ -157,9 +157,10 @@ func (session *Session) SyncWithOptions(opts SyncOptions, beans ...any) (*SyncRe
|
||||
err = nil
|
||||
expectedType := engine.dialect.SQLType(col)
|
||||
curType := engine.dialect.SQLType(oriCol)
|
||||
if expectedType != curType {
|
||||
if expectedType == schemas.Text &&
|
||||
strings.HasPrefix(curType, schemas.Varchar) {
|
||||
switch {
|
||||
case expectedType != curType:
|
||||
switch {
|
||||
case expectedType == schemas.Text && strings.HasPrefix(curType, schemas.Varchar):
|
||||
// currently only support mysql & postgres
|
||||
if engine.dialect.URI().DBType == schemas.MYSQL ||
|
||||
engine.dialect.URI().DBType == schemas.POSTGRES {
|
||||
@@ -170,7 +171,7 @@ func (session *Session) SyncWithOptions(opts SyncOptions, beans ...any) (*SyncRe
|
||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s\n",
|
||||
tbNameWithSchema, col.Name, curType, expectedType)
|
||||
}
|
||||
} else if strings.HasPrefix(curType, schemas.Varchar) && strings.HasPrefix(expectedType, schemas.Varchar) {
|
||||
case strings.HasPrefix(curType, schemas.Varchar) && strings.HasPrefix(expectedType, schemas.Varchar):
|
||||
if engine.dialect.URI().DBType == schemas.POSTGRES ||
|
||||
engine.dialect.URI().DBType == schemas.MYSQL {
|
||||
if oriCol.Length < col.Length {
|
||||
@@ -179,7 +180,7 @@ func (session *Session) SyncWithOptions(opts SyncOptions, beans ...any) (*SyncRe
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSQL(tbNameWithSchema, col))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
default:
|
||||
if !(strings.HasPrefix(curType, expectedType) && curType[len(expectedType)] == '(') {
|
||||
if !strings.EqualFold(schemas.SQLTypeName(curType), engine.dialect.Alias(schemas.SQLTypeName(expectedType))) {
|
||||
engine.logger.Warnf("Table %s column %s db type is %s, struct type is %s",
|
||||
@@ -187,7 +188,7 @@ func (session *Session) SyncWithOptions(opts SyncOptions, beans ...any) (*SyncRe
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if expectedType == schemas.Varchar {
|
||||
case expectedType == schemas.Varchar:
|
||||
if engine.dialect.URI().DBType == schemas.POSTGRES ||
|
||||
engine.dialect.URI().DBType == schemas.MYSQL {
|
||||
if oriCol.Length < col.Length {
|
||||
@@ -196,7 +197,7 @@ func (session *Session) SyncWithOptions(opts SyncOptions, beans ...any) (*SyncRe
|
||||
_, err = session.exec(engine.dialect.ModifyColumnSQL(tbNameWithSchema, col))
|
||||
}
|
||||
}
|
||||
} else if col.Comment != oriCol.Comment {
|
||||
case col.Comment != oriCol.Comment:
|
||||
if engine.dialect.URI().DBType == schemas.POSTGRES ||
|
||||
engine.dialect.URI().DBType == schemas.GBASE8S ||
|
||||
engine.dialect.URI().DBType == schemas.MYSQL {
|
||||
|
||||
+4
-3
@@ -249,11 +249,12 @@ func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, f
|
||||
}
|
||||
|
||||
if col.SQLType.Name == "" {
|
||||
if col.IsJSONB { // check is jsonb first because it is also json
|
||||
switch {
|
||||
case col.IsJSONB: // check is jsonb first because it is also json
|
||||
col.SQLType = schemas.SQLType{Name: schemas.Jsonb}
|
||||
} else if col.IsJSON {
|
||||
case col.IsJSON:
|
||||
col.SQLType = schemas.SQLType{Name: schemas.Json}
|
||||
} else {
|
||||
default:
|
||||
var err error
|
||||
col.SQLType, err = parser.getSQLTypeByType(field.Type)
|
||||
if err != nil {
|
||||
|
||||
@@ -580,7 +580,8 @@ func TestCollate(t *testing.T) {
|
||||
UserId: 1,
|
||||
Name: "Test",
|
||||
})
|
||||
if testEngine.Dialect().URI().DBType == schemas.MYSQL {
|
||||
switch testEngine.Dialect().URI().DBType {
|
||||
case schemas.MYSQL:
|
||||
ver, err1 := testEngine.DBVersion()
|
||||
assert.NoError(t, err1)
|
||||
|
||||
@@ -602,9 +603,9 @@ func TestCollate(t *testing.T) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if testEngine.Dialect().URI().DBType == schemas.MSSQL {
|
||||
case schemas.MSSQL:
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
default:
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -614,12 +615,13 @@ func TestCollate(t *testing.T) {
|
||||
}
|
||||
|
||||
var newCollation string
|
||||
if testEngine.Dialect().URI().DBType == schemas.MYSQL {
|
||||
switch testEngine.Dialect().URI().DBType {
|
||||
case schemas.MYSQL:
|
||||
newCollation = "utf8mb4_bin"
|
||||
} else if testEngine.Dialect().URI().DBType != schemas.MSSQL {
|
||||
newCollation = "Latin1_General_CS_AS"
|
||||
} else {
|
||||
case schemas.MSSQL:
|
||||
return
|
||||
default:
|
||||
newCollation = "Latin1_General_CS_AS"
|
||||
}
|
||||
|
||||
alterSQL := testEngine.Dialect().ModifyColumnSQL("test_collate_column", &schemas.Column{
|
||||
|
||||
+1
-3
@@ -586,9 +586,7 @@ func TestDecimal(t *testing.T) {
|
||||
type MyArray [20]byte
|
||||
|
||||
func (d *MyArray) FromDB(data []byte) error {
|
||||
for i, b := range data[:20] {
|
||||
(*d)[i] = b
|
||||
}
|
||||
copy((*d)[:], data[:20])
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user