require lint before tests

use golangci/golangci-lint-action instead of reviewdog/action-golangci-lint as the second was not reporting any failures even if there was some.

Report code coverage with codecov/codecov-action
I have set some flags per dialect and go version

Several linters has been fixed, some disabled so the build can pass
This commit is contained in:
MOREL Matthieu 2021-12-27 08:26:52 +01:00
parent 2c3fc2db28
commit 21423b914f
63 changed files with 365 additions and 290 deletions

View File

@ -1,11 +0,0 @@
name: reviewdog
on: [pull_request]
jobs:
golangci-lint:
name: runner / golangci-lint
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: golangci-lint
uses: reviewdog/action-golangci-lint@v2

View File

@ -9,8 +9,28 @@ on:
- 'gh-pages' - 'gh-pages'
jobs: jobs:
lint:
name: runner / golangci-lint
runs-on: ubuntu-latest
steps:
- name: Setup go
uses: actions/setup-go@v2
with:
go-version: '1.17'
- name: Checkout repository
uses: actions/checkout@v2
- name: Setup golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: latest
args: --verbose
# Label of the container job # Label of the container job
sqlite: sqlite:
needs: lint
strategy: strategy:
matrix: matrix:
go: ['1.17', '1.16'] go: ['1.17', '1.16']
@ -18,7 +38,7 @@ jobs:
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
- name: Set up Go 1.x - name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
@ -35,7 +55,16 @@ jobs:
- name: Tests - name: Tests
run: GORM_DIALECT=sqlite ./tests/tests_all.sh run: GORM_DIALECT=sqlite ./tests/tests_all.sh
- name: Upload Code Coverage
uses: codecov/codecov-action@v2
with:
name: sqlite
flags: sqlite,go-${{ matrix.go }}
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
mysql: mysql:
needs: lint
strategy: strategy:
matrix: matrix:
dbversion: ['mysql:latest', 'mysql:5.7', 'mariadb:latest'] dbversion: ['mysql:latest', 'mysql:5.7', 'mariadb:latest']
@ -61,7 +90,7 @@ jobs:
--health-retries 10 --health-retries 10
steps: steps:
- name: Set up Go 1.x - name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
@ -69,7 +98,6 @@ jobs:
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: go mod package cache - name: go mod package cache
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
@ -79,7 +107,16 @@ jobs:
- name: Tests - name: Tests
run: GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True" ./tests/tests_all.sh run: GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True" ./tests/tests_all.sh
- name: Upload Code Coverage
uses: codecov/codecov-action@v2
with:
name: mysql
flags: mysql,go-${{ matrix.go }}
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
postgres: postgres:
needs: lint
strategy: strategy:
matrix: matrix:
dbversion: ['postgres:latest', 'postgres:13', 'postgres:12', 'postgres:11', 'postgres:10'] dbversion: ['postgres:latest', 'postgres:13', 'postgres:12', 'postgres:11', 'postgres:10']
@ -105,7 +142,7 @@ jobs:
--health-retries 5 --health-retries 5
steps: steps:
- name: Set up Go 1.x - name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
@ -122,7 +159,16 @@ jobs:
- name: Tests - name: Tests
run: GORM_DIALECT=postgres GORM_DSN="user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai" ./tests/tests_all.sh run: GORM_DIALECT=postgres GORM_DSN="user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai" ./tests/tests_all.sh
- name: Upload Code Coverage
uses: codecov/codecov-action@v2
with:
name: postgres
flags: postgres,go-${{ matrix.go }}
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
sqlserver: sqlserver:
needs: lint
strategy: strategy:
matrix: matrix:
go: ['1.17', '1.16'] go: ['1.17', '1.16']
@ -148,7 +194,7 @@ jobs:
--health-retries 10 --health-retries 10
steps: steps:
- name: Set up Go 1.x - name: Set up Go ${{ matrix.go }}
uses: actions/setup-go@v2 uses: actions/setup-go@v2
with: with:
go-version: ${{ matrix.go }} go-version: ${{ matrix.go }}
@ -164,3 +210,11 @@ jobs:
- name: Tests - name: Tests
run: GORM_DIALECT=sqlserver GORM_DSN="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" ./tests/tests_all.sh run: GORM_DIALECT=sqlserver GORM_DSN="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" ./tests/tests_all.sh
- name: Upload Code Coverage
uses: codecov/codecov-action@v2
with:
name: sqlserver
flags: sqlserver,go-${{ matrix.go }}
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}

View File

@ -1,11 +1,33 @@
linters: linters:
enable: disable:
- cyclop - cyclop
- exportloopref - errcheck
- gocritic
- gosec - gosec
- ineffassign - ineffassign
- staticcheck
- structcheck
enable:
- errorlint
- exportloopref
- gci
- gocritic
- gofumpt
- misspell - misspell
- prealloc - prealloc
- unconvert - unconvert
- unparam - unparam
issues:
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
exclude-rules:
- linters:
- gocritic
text: "singleCaseSwitch"
- linters:
- gocritic
text: "ifElseChain"
linters-settings:
gci:
local-prefixes: gorm.io/gorm

View File

@ -241,8 +241,9 @@ func getRIndex(strs []string, str string) int {
} }
func sortCallbacks(cs []*callback) (fns []func(*DB), err error) { func sortCallbacks(cs []*callback) (fns []func(*DB), err error) {
names := make([]string, 0)
var ( var (
names, sorted []string sorted []string
sortCallback func(*callback) error sortCallback func(*callback) error
) )
sort.Slice(cs, func(i, j int) bool { sort.Slice(cs, func(i, j int) bool {

View File

@ -323,7 +323,7 @@ func SaveAfterAssociations(create bool) func(db *gorm.DB) {
} }
} }
func onConflictOption(stmt *gorm.Statement, s *schema.Schema, selectColumns map[string]bool, restricted bool, defaultUpdatingColumns []string) (onConflict clause.OnConflict) { func onConflictOption(stmt *gorm.Statement, s *schema.Schema, defaultUpdatingColumns []string) (onConflict clause.OnConflict) {
if len(defaultUpdatingColumns) > 0 || stmt.DB.FullSaveAssociations { if len(defaultUpdatingColumns) > 0 || stmt.DB.FullSaveAssociations {
onConflict.Columns = make([]clause.Column, 0, len(s.PrimaryFieldDBNames)) onConflict.Columns = make([]clause.Column, 0, len(s.PrimaryFieldDBNames))
for _, dbName := range s.PrimaryFieldDBNames { for _, dbName := range s.PrimaryFieldDBNames {
@ -344,7 +344,7 @@ func onConflictOption(stmt *gorm.Statement, s *schema.Schema, selectColumns map[
func saveAssociations(db *gorm.DB, rel *schema.Relationship, values interface{}, selectColumns map[string]bool, restricted bool, defaultUpdatingColumns []string) error { func saveAssociations(db *gorm.DB, rel *schema.Relationship, values interface{}, selectColumns map[string]bool, restricted bool, defaultUpdatingColumns []string) error {
var ( var (
selects, omits []string selects, omits []string
onConflict = onConflictOption(db.Statement, rel.FieldSchema, selectColumns, restricted, defaultUpdatingColumns) onConflict = onConflictOption(db.Statement, rel.FieldSchema, defaultUpdatingColumns)
refName = rel.Name + "." refName = rel.Name + "."
) )

View File

@ -12,7 +12,7 @@ func ConvertMapToValuesForCreate(stmt *gorm.Statement, mapValue map[string]inter
values.Columns = make([]clause.Column, 0, len(mapValue)) values.Columns = make([]clause.Column, 0, len(mapValue))
selectColumns, restricted := stmt.SelectAndOmitColumns(true, false) selectColumns, restricted := stmt.SelectAndOmitColumns(true, false)
var keys = make([]string, 0, len(mapValue)) keys := make([]string, 0, len(mapValue))
for k := range mapValue { for k := range mapValue {
keys = append(keys, k) keys = append(keys, k)
} }
@ -40,9 +40,7 @@ func ConvertMapToValuesForCreate(stmt *gorm.Statement, mapValue map[string]inter
// ConvertSliceOfMapToValuesForCreate convert slice of map to values // ConvertSliceOfMapToValuesForCreate convert slice of map to values
func ConvertSliceOfMapToValuesForCreate(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) { func ConvertSliceOfMapToValuesForCreate(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) {
var ( columns := make([]string, 0, len(mapValues))
columns = make([]string, 0, len(mapValues))
)
// when the length of mapValues is zero,return directly here // when the length of mapValues is zero,return directly here
// no need to call stmt.SelectAndOmitColumns method // no need to call stmt.SelectAndOmitColumns method

View File

@ -1,6 +1,8 @@
package callbacks package callbacks
import ( import (
"errors"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -9,7 +11,7 @@ func BeginTransaction(db *gorm.DB) {
if tx := db.Begin(); tx.Error == nil { if tx := db.Begin(); tx.Error == nil {
db.Statement.ConnPool = tx.Statement.ConnPool db.Statement.ConnPool = tx.Statement.ConnPool
db.InstanceSet("gorm:started_transaction", true) db.InstanceSet("gorm:started_transaction", true)
} else if tx.Error == gorm.ErrInvalidTransaction { } else if errors.Is(tx.Error, gorm.ErrInvalidTransaction) {
tx.Error = nil tx.Error = nil
} else { } else {
db.Error = tx.Error db.Error = tx.Error

View File

@ -162,7 +162,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
if size := stmt.ReflectValue.Len(); size > 0 { if size := stmt.ReflectValue.Len(); size > 0 {
var primaryKeyExprs []clause.Expression var primaryKeyExprs []clause.Expression
for i := 0; i < size; i++ { for i := 0; i < size; i++ {
var exprs = make([]clause.Expression, len(stmt.Schema.PrimaryFields)) exprs := make([]clause.Expression, len(stmt.Schema.PrimaryFields))
var notZero bool var notZero bool
for idx, field := range stmt.Schema.PrimaryFields { for idx, field := range stmt.Schema.PrimaryFields {
value, isZero := field.ValueOf(stmt.ReflectValue.Index(i)) value, isZero := field.ValueOf(stmt.ReflectValue.Index(i))
@ -242,7 +242,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) {
} }
} }
default: default:
var updatingSchema = stmt.Schema updatingSchema := stmt.Schema
if !updatingValue.CanAddr() || stmt.Dest != stmt.Model { if !updatingValue.CanAddr() || stmt.Dest != stmt.Model {
// different schema // different schema
updatingStmt := &gorm.Statement{DB: stmt.DB} updatingStmt := &gorm.Statement{DB: stmt.DB}

View File

@ -32,7 +32,8 @@ func BenchmarkComplexSelect(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
stmt := gorm.Statement{DB: db, Table: user.Table, Schema: user, Clauses: map[string]clause.Clause{}} stmt := gorm.Statement{DB: db, Table: user.Table, Schema: user, Clauses: map[string]clause.Clause{}}
clauses := []clause.Interface{ clauses := []clause.Interface{
clause.Select{}, clause.From{}, clause.Select{},
clause.From{},
clause.Where{Exprs: []clause.Expression{ clause.Where{Exprs: []clause.Expression{
clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Eq{Column: clause.PrimaryColumn, Value: "1"},
clause.Gt{Column: "age", Value: 18}, clause.Gt{Column: "age", Value: 18},

View File

@ -18,7 +18,8 @@ func TestGroupBy(t *testing.T) {
Columns: []clause.Column{{Name: "role"}}, Columns: []clause.Column{{Name: "role"}},
Having: []clause.Expression{clause.Eq{"role", "admin"}}, Having: []clause.Expression{clause.Eq{"role", "admin"}},
}}, }},
"SELECT * FROM `users` GROUP BY `role` HAVING `role` = ?", []interface{}{"admin"}, "SELECT * FROM `users` GROUP BY `role` HAVING `role` = ?",
[]interface{}{"admin"},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{ []clause.Interface{clause.Select{}, clause.From{}, clause.GroupBy{
@ -28,7 +29,8 @@ func TestGroupBy(t *testing.T) {
Columns: []clause.Column{{Name: "gender"}}, Columns: []clause.Column{{Name: "gender"}},
Having: []clause.Expression{clause.Neq{"gender", "U"}}, Having: []clause.Expression{clause.Neq{"gender", "U"}},
}}, }},
"SELECT * FROM `users` GROUP BY `role`,`gender` HAVING `role` = ? AND `gender` <> ?", []interface{}{"admin", "U"}, "SELECT * FROM `users` GROUP BY `role`,`gender` HAVING `role` = ? AND `gender` <> ?",
[]interface{}{"admin", "U"},
}, },
} }

View File

@ -45,7 +45,8 @@ func TestOrderBy(t *testing.T) {
Expression: clause.Expr{SQL: "FIELD(id, ?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true}, Expression: clause.Expr{SQL: "FIELD(id, ?)", Vars: []interface{}{[]int{1, 2, 3}}, WithoutParentheses: true},
}, },
}, },
"SELECT * FROM `users` ORDER BY FIELD(id, ?,?,?)", []interface{}{1, 2, 3}, "SELECT * FROM `users` ORDER BY FIELD(id, ?,?,?)",
[]interface{}{1, 2, 3},
}, },
} }

View File

@ -20,7 +20,8 @@ func TestSet(t *testing.T) {
clause.Update{}, clause.Update{},
clause.Set([]clause.Assignment{{clause.PrimaryColumn, 1}}), clause.Set([]clause.Assignment{{clause.PrimaryColumn, 1}}),
}, },
"UPDATE `users` SET `users`.`id`=?", []interface{}{1}, "UPDATE `users` SET `users`.`id`=?",
[]interface{}{1},
}, },
{ {
[]clause.Interface{ []clause.Interface{
@ -28,7 +29,8 @@ func TestSet(t *testing.T) {
clause.Set([]clause.Assignment{{clause.PrimaryColumn, 1}}), clause.Set([]clause.Assignment{{clause.PrimaryColumn, 1}}),
clause.Set([]clause.Assignment{{clause.Column{Name: "name"}, "jinzhu"}}), clause.Set([]clause.Assignment{{clause.Column{Name: "name"}, "jinzhu"}}),
}, },
"UPDATE `users` SET `name`=?", []interface{}{"jinzhu"}, "UPDATE `users` SET `name`=?",
[]interface{}{"jinzhu"},
}, },
} }

View File

@ -21,7 +21,8 @@ func TestValues(t *testing.T) {
Values: [][]interface{}{{"jinzhu", 18}, {"josh", 1}}, Values: [][]interface{}{{"jinzhu", 18}, {"josh", 1}},
}, },
}, },
"INSERT INTO `users` (`name`,`age`) VALUES (?,?),(?,?)", []interface{}{"jinzhu", 18, "josh", 1}, "INSERT INTO `users` (`name`,`age`) VALUES (?,?),(?,?)",
[]interface{}{"jinzhu", 18, "josh", 1},
}, },
} }

View File

@ -17,25 +17,29 @@ func TestWhere(t *testing.T) {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}, clause.Or(clause.Neq{Column: "name", Value: "jinzhu"})}, Exprs: []clause.Expression{clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}, clause.Or(clause.Neq{Column: "name", Value: "jinzhu"})},
}}, }},
"SELECT * FROM `users` WHERE `users`.`id` = ? AND `age` > ? OR `name` <> ?", []interface{}{"1", 18, "jinzhu"}, "SELECT * FROM `users` WHERE `users`.`id` = ? AND `age` > ? OR `name` <> ?",
[]interface{}{"1", 18, "jinzhu"},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.Or(clause.Neq{Column: "name", Value: "jinzhu"}), clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}}, Exprs: []clause.Expression{clause.Or(clause.Neq{Column: "name", Value: "jinzhu"}), clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}},
}}, }},
"SELECT * FROM `users` WHERE `users`.`id` = ? OR `name` <> ? AND `age` > ?", []interface{}{"1", "jinzhu", 18}, "SELECT * FROM `users` WHERE `users`.`id` = ? OR `name` <> ? AND `age` > ?",
[]interface{}{"1", "jinzhu", 18},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.Or(clause.Neq{Column: "name", Value: "jinzhu"}), clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}}, Exprs: []clause.Expression{clause.Or(clause.Neq{Column: "name", Value: "jinzhu"}), clause.Eq{Column: clause.PrimaryColumn, Value: "1"}, clause.Gt{Column: "age", Value: 18}},
}}, }},
"SELECT * FROM `users` WHERE `users`.`id` = ? OR `name` <> ? AND `age` > ?", []interface{}{"1", "jinzhu", 18}, "SELECT * FROM `users` WHERE `users`.`id` = ? OR `name` <> ? AND `age` > ?",
[]interface{}{"1", "jinzhu", 18},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.Or(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}), clause.Or(clause.Neq{Column: "name", Value: "jinzhu"})}, Exprs: []clause.Expression{clause.Or(clause.Eq{Column: clause.PrimaryColumn, Value: "1"}), clause.Or(clause.Neq{Column: "name", Value: "jinzhu"})},
}}, }},
"SELECT * FROM `users` WHERE `users`.`id` = ? OR `name` <> ?", []interface{}{"1", "jinzhu"}, "SELECT * FROM `users` WHERE `users`.`id` = ? OR `name` <> ?",
[]interface{}{"1", "jinzhu"},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
@ -43,7 +47,8 @@ func TestWhere(t *testing.T) {
}, clause.Where{ }, clause.Where{
Exprs: []clause.Expression{clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"})}, Exprs: []clause.Expression{clause.Or(clause.Gt{Column: "score", Value: 100}, clause.Like{Column: "name", Value: "%linus%"})},
}}, }},
"SELECT * FROM `users` WHERE `users`.`id` = ? AND `age` > ? OR `name` <> ? AND (`score` > ? OR `name` LIKE ?)", []interface{}{"1", 18, "jinzhu", 100, "%linus%"}, "SELECT * FROM `users` WHERE `users`.`id` = ? AND `age` > ? OR `name` <> ? AND (`score` > ? OR `name` LIKE ?)",
[]interface{}{"1", 18, "jinzhu", 100, "%linus%"},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
@ -51,13 +56,15 @@ func TestWhere(t *testing.T) {
}, clause.Where{ }, clause.Where{
Exprs: []clause.Expression{clause.Or(clause.Not(clause.Gt{Column: "score", Value: 100}), clause.Like{Column: "name", Value: "%linus%"})}, Exprs: []clause.Expression{clause.Or(clause.Not(clause.Gt{Column: "score", Value: 100}), clause.Like{Column: "name", Value: "%linus%"})},
}}, }},
"SELECT * FROM `users` WHERE (`users`.`id` <> ? AND `age` <= ?) OR `name` <> ? AND (`score` <= ? OR `name` LIKE ?)", []interface{}{"1", 18, "jinzhu", 100, "%linus%"}, "SELECT * FROM `users` WHERE (`users`.`id` <> ? AND `age` <= ?) OR `name` <> ? AND (`score` <= ? OR `name` LIKE ?)",
[]interface{}{"1", 18, "jinzhu", 100, "%linus%"},
}, },
{ {
[]clause.Interface{clause.Select{}, clause.From{}, clause.Where{ []clause.Interface{clause.Select{}, clause.From{}, clause.Where{
Exprs: []clause.Expression{clause.And(clause.Eq{Column: "age", Value: 18}, clause.Or(clause.Neq{Column: "name", Value: "jinzhu"}))}, Exprs: []clause.Expression{clause.And(clause.Eq{Column: "age", Value: 18}, clause.Or(clause.Neq{Column: "name", Value: "jinzhu"}))},
}}, }},
"SELECT * FROM `users` WHERE (`age` = ? OR `name` <> ?)", []interface{}{18, "jinzhu"}, "SELECT * FROM `users` WHERE (`age` = ? OR `name` <> ?)",
[]interface{}{18, "jinzhu"},
}, },
} }

View File

@ -1,4 +1,3 @@
package clause package clause
type With struct { type With struct{}
}

View File

@ -32,7 +32,7 @@ var convertibleTypes = []reflect.Type{reflect.TypeOf(time.Time{}), reflect.TypeO
func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, avars ...interface{}) string { func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, avars ...interface{}) string {
var convertParams func(interface{}, int) var convertParams func(interface{}, int)
var vars = make([]string, len(avars)) vars := make([]string, len(avars))
convertParams = func(v interface{}, idx int) { convertParams = func(v interface{}, idx int) {
switch v := v.(type) { switch v := v.(type) {
@ -65,13 +65,13 @@ func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, a
case fmt.Stringer: case fmt.Stringer:
reflectValue := reflect.ValueOf(v) reflectValue := reflect.ValueOf(v)
if v != nil && reflectValue.IsValid() && ((reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil()) || reflectValue.Kind() != reflect.Ptr) { if v != nil && reflectValue.IsValid() && ((reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil()) || reflectValue.Kind() != reflect.Ptr) {
vars[idx] = escaper + strings.Replace(fmt.Sprintf("%v", v), escaper, "\\"+escaper, -1) + escaper vars[idx] = escaper + strings.ReplaceAll(fmt.Sprintf("%v", v), escaper, "\\"+escaper) + escaper
} else { } else {
vars[idx] = nullStr vars[idx] = nullStr
} }
case []byte: case []byte:
if isPrintable(v) { if isPrintable(v) {
vars[idx] = escaper + strings.Replace(string(v), escaper, "\\"+escaper, -1) + escaper vars[idx] = escaper + strings.ReplaceAll(string(v), escaper, "\\"+escaper) + escaper
} else { } else {
vars[idx] = escaper + "<binary>" + escaper vars[idx] = escaper + "<binary>" + escaper
} }
@ -80,7 +80,7 @@ func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, a
case float64, float32: case float64, float32:
vars[idx] = fmt.Sprintf("%.6f", v) vars[idx] = fmt.Sprintf("%.6f", v)
case string: case string:
vars[idx] = escaper + strings.Replace(v, escaper, "\\"+escaper, -1) + escaper vars[idx] = escaper + strings.ReplaceAll(v, escaper, "\\"+escaper) + escaper
default: default:
rv := reflect.ValueOf(v) rv := reflect.ValueOf(v)
if v == nil || !rv.IsValid() || rv.Kind() == reflect.Ptr && rv.IsNil() { if v == nil || !rv.IsValid() || rv.Kind() == reflect.Ptr && rv.IsNil() {
@ -97,7 +97,7 @@ func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, a
return return
} }
} }
vars[idx] = escaper + strings.Replace(fmt.Sprint(v), escaper, "\\"+escaper, -1) + escaper vars[idx] = escaper + strings.ReplaceAll(fmt.Sprint(v), escaper, "\\"+escaper) + escaper
} }
} }
} }

View File

@ -9,6 +9,7 @@ import (
"testing" "testing"
"github.com/jinzhu/now" "github.com/jinzhu/now"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
) )
@ -30,8 +31,9 @@ func (s ExampleStruct) Value() (driver.Value, error) {
return json.Marshal(s) return json.Marshal(s)
} }
func format(v []byte, escaper string) string { func format(v []byte) string {
return escaper + strings.Replace(string(v), escaper, "\\"+escaper, -1) + escaper escaper := `"`
return escaper + strings.ReplaceAll(string(v), escaper, "\\"+escaper) + escaper
} }
func TestExplainSQL(t *testing.T) { func TestExplainSQL(t *testing.T) {
@ -87,13 +89,13 @@ func TestExplainSQL(t *testing.T) {
SQL: "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", SQL: "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
NumericRegexp: nil, NumericRegexp: nil,
Vars: []interface{}{"jinzhu", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, js, es}, Vars: []interface{}{"jinzhu", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, js, es},
Result: fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.\"com", "admin", "pass", %v, %v)`, format(jsVal, `"`), format(esVal, `"`)), Result: fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.\"com", "admin", "pass", %v, %v)`, format(jsVal), format(esVal)),
}, },
{ {
SQL: "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", SQL: "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
NumericRegexp: nil, NumericRegexp: nil,
Vars: []interface{}{"jinzhu", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, &js, &es}, Vars: []interface{}{"jinzhu", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, &js, &es},
Result: fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.\"com", "admin", "pass", %v, %v)`, format(jsVal, `"`), format(esVal, `"`)), Result: fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.\"com", "admin", "pass", %v, %v)`, format(jsVal), format(esVal)),
}, },
} }

View File

@ -474,7 +474,8 @@ func buildConstraint(constraint *schema.Constraint) (sql string, results []inter
sql += " ON UPDATE " + constraint.OnUpdate sql += " ON UPDATE " + constraint.OnUpdate
} }
var foreignKeys, references []interface{} foreignKeys := make([]interface{}, 0)
references := make([]interface{}, 0)
for _, field := range constraint.ForeignKeys { for _, field := range constraint.ForeignKeys {
foreignKeys = append(foreignKeys, clause.Column{Name: field.DBName}) foreignKeys = append(foreignKeys, clause.Column{Name: field.DBName})
} }
@ -541,7 +542,7 @@ func (m Migrator) CreateConstraint(value interface{}, name string) error {
} }
if constraint != nil { if constraint != nil {
var vars = []interface{}{clause.Table{Name: table}} vars := []interface{}{clause.Table{Name: table}}
if stmt.TableExpr != nil { if stmt.TableExpr != nil {
vars[0] = stmt.TableExpr vars[0] = stmt.TableExpr
} }

View File

@ -3,6 +3,7 @@ package gorm
import ( import (
"database/sql" "database/sql"
"database/sql/driver" "database/sql/driver"
"errors"
"reflect" "reflect"
"strings" "strings"
"time" "time"
@ -49,7 +50,7 @@ func scanIntoMap(mapValue map[string]interface{}, values []interface{}, columns
} }
} }
func (db *DB) scanIntoStruct(sch *schema.Schema, rows *sql.Rows, reflectValue reflect.Value, values []interface{}, columns []string, fields []*schema.Field, joinFields [][2]*schema.Field) { func (db *DB) scanIntoStruct(sch *schema.Schema, rows *sql.Rows, reflectValue reflect.Value, values []interface{}, columns []string) {
for idx, column := range columns { for idx, column := range columns {
if sch == nil { if sch == nil {
values[idx] = reflectValue.Interface() values[idx] = reflectValue.Interface()
@ -254,7 +255,7 @@ func Scan(rows *sql.Rows, db *DB, mode ScanMode) {
elem = reflect.New(reflectValueType) elem = reflect.New(reflectValueType)
} }
db.scanIntoStruct(sch, rows, elem, values, columns, fields, joinFields) db.scanIntoStruct(sch, rows, elem, values, columns)
if !update { if !update {
if isPtr { if isPtr {
@ -270,14 +271,14 @@ func Scan(rows *sql.Rows, db *DB, mode ScanMode) {
} }
case reflect.Struct, reflect.Ptr: case reflect.Struct, reflect.Ptr:
if initialized || rows.Next() { if initialized || rows.Next() {
db.scanIntoStruct(sch, rows, reflectValue, values, columns, fields, joinFields) db.scanIntoStruct(sch, rows, reflectValue, values, columns)
} }
default: default:
db.AddError(rows.Scan(dest)) db.AddError(rows.Scan(dest))
} }
} }
if err := rows.Err(); err != nil && err != db.Error { if err := rows.Err(); err != nil && !errors.Is(err, db.Error) {
db.AddError(err) db.AddError(err)
} }

View File

@ -9,8 +9,7 @@ import (
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
) )
type UserWithCallback struct { type UserWithCallback struct{}
}
func (UserWithCallback) BeforeSave(*gorm.DB) error { func (UserWithCallback) BeforeSave(*gorm.DB) error {
return nil return nil

View File

@ -5,10 +5,8 @@ import (
"strings" "strings"
) )
var (
// reg match english letters and midline // reg match english letters and midline
regEnLetterAndMidline = regexp.MustCompile("^[A-Za-z-_]+$") var regEnLetterAndMidline = regexp.MustCompile("^[A-Za-z-_]+$")
)
type Check struct { type Check struct {
Name string Name string
@ -18,7 +16,7 @@ type Check struct {
// ParseCheckConstraints parse schema check constraints // ParseCheckConstraints parse schema check constraints
func (schema *Schema) ParseCheckConstraints() map[string]Check { func (schema *Schema) ParseCheckConstraints() map[string]Check {
var checks = map[string]Check{} checks := map[string]Check{}
for _, field := range schema.FieldsByDBName { for _, field := range schema.FieldsByDBName {
if chk := field.TagSettings["CHECK"]; chk != "" { if chk := field.TagSettings["CHECK"]; chk != "" {
names := strings.Split(chk, ",") names := strings.Split(chk, ",")

View File

@ -11,6 +11,7 @@ import (
"time" "time"
"github.com/jinzhu/now" "github.com/jinzhu/now"
"gorm.io/gorm/utils" "gorm.io/gorm/utils"
) )
@ -199,28 +200,28 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field {
field.DataType = Bool field.DataType = Bool
if field.HasDefaultValue && !skipParseDefaultValue { if field.HasDefaultValue && !skipParseDefaultValue {
if field.DefaultValueInterface, err = strconv.ParseBool(field.DefaultValue); err != nil { if field.DefaultValueInterface, err = strconv.ParseBool(field.DefaultValue); err != nil {
schema.err = fmt.Errorf("failed to parse %s as default value for bool, got error: %v", field.DefaultValue, err) schema.err = fmt.Errorf("failed to parse %s as default value for bool, got error: %w", field.DefaultValue, err)
} }
} }
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
field.DataType = Int field.DataType = Int
if field.HasDefaultValue && !skipParseDefaultValue { if field.HasDefaultValue && !skipParseDefaultValue {
if field.DefaultValueInterface, err = strconv.ParseInt(field.DefaultValue, 0, 64); err != nil { if field.DefaultValueInterface, err = strconv.ParseInt(field.DefaultValue, 0, 64); err != nil {
schema.err = fmt.Errorf("failed to parse %s as default value for int, got error: %v", field.DefaultValue, err) schema.err = fmt.Errorf("failed to parse %s as default value for int, got error: %w", field.DefaultValue, err)
} }
} }
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
field.DataType = Uint field.DataType = Uint
if field.HasDefaultValue && !skipParseDefaultValue { if field.HasDefaultValue && !skipParseDefaultValue {
if field.DefaultValueInterface, err = strconv.ParseUint(field.DefaultValue, 0, 64); err != nil { if field.DefaultValueInterface, err = strconv.ParseUint(field.DefaultValue, 0, 64); err != nil {
schema.err = fmt.Errorf("failed to parse %s as default value for uint, got error: %v", field.DefaultValue, err) schema.err = fmt.Errorf("failed to parse %s as default value for uint, got error: %w", field.DefaultValue, err)
} }
} }
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
field.DataType = Float field.DataType = Float
if field.HasDefaultValue && !skipParseDefaultValue { if field.HasDefaultValue && !skipParseDefaultValue {
if field.DefaultValueInterface, err = strconv.ParseFloat(field.DefaultValue, 64); err != nil { if field.DefaultValueInterface, err = strconv.ParseFloat(field.DefaultValue, 64); err != nil {
schema.err = fmt.Errorf("failed to parse %s as default value for float, got error: %v", field.DefaultValue, err) schema.err = fmt.Errorf("failed to parse %s as default value for float, got error: %w", field.DefaultValue, err)
} }
} }
case reflect.String: case reflect.String:
@ -745,7 +746,7 @@ func (field *Field) setupValuerAndSetter() {
if t, err := now.Parse(data); err == nil { if t, err := now.Parse(data); err == nil {
field.ReflectValueOf(value).Set(reflect.ValueOf(t)) field.ReflectValueOf(value).Set(reflect.ValueOf(t))
} else { } else {
return fmt.Errorf("failed to set string %v to time.Time field %s, failed to parse it as time, got error %v", v, field.Name, err) return fmt.Errorf("failed to set string %v to time.Time field %s, failed to parse it as time, got error %w", v, field.Name, err)
} }
default: default:
return fallbackSetter(value, v, field.Set) return fallbackSetter(value, v, field.Set)
@ -774,7 +775,7 @@ func (field *Field) setupValuerAndSetter() {
} }
fieldValue.Elem().Set(reflect.ValueOf(t)) fieldValue.Elem().Set(reflect.ValueOf(t))
} else { } else {
return fmt.Errorf("failed to set string %v to time.Time field %s, failed to parse it as time, got error %v", v, field.Name, err) return fmt.Errorf("failed to set string %v to time.Time field %s, failed to parse it as time, got error %w", v, field.Name, err)
} }
default: default:
return fallbackSetter(value, v, field.Set) return fallbackSetter(value, v, field.Set)

View File

@ -261,22 +261,23 @@ func TestParseFieldWithPermission(t *testing.T) {
} }
} }
type ID int64 type (
type INT int ID int64
type INT8 int8 INT int
type INT16 int16 INT8 int8
type INT32 int32 INT16 int16
type INT64 int64 INT32 int32
type UINT uint INT64 int64
type UINT8 uint8 UINT uint
type UINT16 uint16 UINT8 uint8
type UINT32 uint32 UINT16 uint16
type UINT64 uint64 UINT32 uint32
type FLOAT32 float32 UINT64 uint64
type FLOAT64 float64 FLOAT32 float32
type BOOL bool FLOAT64 float64
type STRING string BOOL bool
type TypeAlias struct { STRING string
TypeAlias struct {
ID ID
INT `gorm:"column:fint"` INT `gorm:"column:fint"`
INT8 `gorm:"column:fint8"` INT8 `gorm:"column:fint8"`
@ -293,6 +294,7 @@ type TypeAlias struct {
BOOL `gorm:"column:fbool"` BOOL `gorm:"column:fbool"`
STRING `gorm:"column:fstring"` STRING `gorm:"column:fstring"`
} }
)
func TestTypeAliasField(t *testing.T) { func TestTypeAliasField(t *testing.T) {
alias, err := schema.Parse(&TypeAlias{}, &sync.Map{}, schema.NamingStrategy{}) alias, err := schema.Parse(&TypeAlias{}, &sync.Map{}, schema.NamingStrategy{})

View File

@ -27,7 +27,7 @@ type IndexOption struct {
// ParseIndexes parse schema indexes // ParseIndexes parse schema indexes
func (schema *Schema) ParseIndexes() map[string]Index { func (schema *Schema) ParseIndexes() map[string]Index {
var indexes = map[string]Index{} indexes := map[string]Index{}
for _, field := range schema.Fields { for _, field := range schema.Fields {
if field.TagSettings["INDEX"] != "" || field.TagSettings["UNIQUEINDEX"] != "" { if field.TagSettings["INDEX"] != "" || field.TagSettings["UNIQUEINDEX"] != "" {

View File

@ -26,9 +26,11 @@ type User struct {
Active *bool Active *bool
} }
type mytime time.Time type (
type myint int mytime time.Time
type mybool = bool myint int
mybool = bool
)
type AdvancedDataTypeUser struct { type AdvancedDataTypeUser struct {
ID sql.NullInt64 ID sql.NullInt64

View File

@ -86,9 +86,9 @@ func (ns NamingStrategy) IndexName(table, column string) string {
} }
func (ns NamingStrategy) formatName(prefix, table, name string) string { func (ns NamingStrategy) formatName(prefix, table, name string) string {
formattedName := strings.Replace(strings.Join([]string{ formattedName := strings.ReplaceAll(strings.Join([]string{
prefix, table, name, prefix, table, name,
}, "_"), ".", "_", -1) }, "_"), ".", "_")
if utf8.RuneCountInString(formattedName) > 64 { if utf8.RuneCountInString(formattedName) > 64 {
h := sha1.New() h := sha1.New()
@ -168,7 +168,7 @@ func (ns NamingStrategy) toDBName(name string) string {
} }
func (ns NamingStrategy) toSchemaName(name string) string { func (ns NamingStrategy) toSchemaName(name string) string {
result := strings.Replace(strings.Title(strings.Replace(name, "_", " ", -1)), " ", "", -1) result := strings.ReplaceAll(strings.Title(strings.ReplaceAll(name, "_", " ")), " ", "")
for _, initialism := range commonInitialisms { for _, initialism := range commonInitialisms {
result = regexp.MustCompile(strings.Title(strings.ToLower(initialism))+"([A-Z]|$|_)").ReplaceAllString(result, initialism+"$1") result = regexp.MustCompile(strings.Title(strings.ToLower(initialism))+"([A-Z]|$|_)").ReplaceAllString(result, initialism+"$1")
} }

View File

@ -6,7 +6,7 @@ import (
) )
func TestToDBName(t *testing.T) { func TestToDBName(t *testing.T) {
var maps = map[string]string{ maps := map[string]string{
"": "", "": "",
"x": "x", "x": "x",
"X": "x", "X": "x",
@ -56,7 +56,7 @@ func TestToDBName(t *testing.T) {
} }
func TestNamingStrategy(t *testing.T) { func TestNamingStrategy(t *testing.T) {
var ns = NamingStrategy{ ns := NamingStrategy{
TablePrefix: "public.", TablePrefix: "public.",
SingularTable: true, SingularTable: true,
NameReplacer: strings.NewReplacer("CID", "Cid"), NameReplacer: strings.NewReplacer("CID", "Cid"),
@ -102,7 +102,7 @@ func (r CustomReplacer) Replace(name string) string {
} }
func TestCustomReplacer(t *testing.T) { func TestCustomReplacer(t *testing.T) {
var ns = NamingStrategy{ ns := NamingStrategy{
TablePrefix: "public.", TablePrefix: "public.",
SingularTable: true, SingularTable: true,
NameReplacer: CustomReplacer{ NameReplacer: CustomReplacer{
@ -146,7 +146,7 @@ func TestCustomReplacer(t *testing.T) {
} }
func TestCustomReplacerWithNoLowerCase(t *testing.T) { func TestCustomReplacerWithNoLowerCase(t *testing.T) {
var ns = NamingStrategy{ ns := NamingStrategy{
TablePrefix: "public.", TablePrefix: "public.",
SingularTable: true, SingularTable: true,
NameReplacer: CustomReplacer{ NameReplacer: CustomReplacer{
@ -190,7 +190,7 @@ func TestCustomReplacerWithNoLowerCase(t *testing.T) {
} }
func TestFormatNameWithStringLongerThan64Characters(t *testing.T) { func TestFormatNameWithStringLongerThan64Characters(t *testing.T) {
var ns = NamingStrategy{} ns := NamingStrategy{}
formattedName := ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString") formattedName := ns.formatName("prefix", "table", "thisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLongString")
if formattedName != "prefixtablethisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLo180f2c67" { if formattedName != "prefixtablethisIsAVeryVeryVeryVeryVeryVeryVeryVeryVeryLo180f2c67" {

View File

@ -6,6 +6,7 @@ import (
"strings" "strings"
"github.com/jinzhu/inflection" "github.com/jinzhu/inflection"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
) )
@ -186,9 +187,9 @@ func (schema *Schema) buildPolymorphicRelation(relation *Relationship, field *Fi
func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Field, many2many string) { func (schema *Schema) buildMany2ManyRelation(relation *Relationship, field *Field, many2many string) {
relation.Type = Many2Many relation.Type = Many2Many
joinTableFields := make([]reflect.StructField, 0)
var ( var (
err error err error
joinTableFields []reflect.StructField
fieldsMap = map[string]*Field{} fieldsMap = map[string]*Field{}
ownFieldsMap = map[string]bool{} // fix self join many2many ownFieldsMap = map[string]bool{} // fix self join many2many
joinForeignKeys = toColumns(field.TagSettings["JOINFOREIGNKEY"]) joinForeignKeys = toColumns(field.TagSettings["JOINFOREIGNKEY"])

View File

@ -105,7 +105,6 @@ func TestSelfReferentialBelongsTo(t *testing.T) {
Name: "Creator", Type: schema.BelongsTo, Schema: "User", FieldSchema: "User", Name: "Creator", Type: schema.BelongsTo, Schema: "User", FieldSchema: "User",
References: []Reference{{"ID", "User", "CreatorID", "User", "", false}}, References: []Reference{{"ID", "User", "CreatorID", "User", "", false}},
}) })
} }
func TestSelfReferentialBelongsToOverrideReferences(t *testing.T) { func TestSelfReferentialBelongsToOverrideReferences(t *testing.T) {
@ -160,7 +159,6 @@ func TestHasOneOverrideReferences(t *testing.T) {
} }
func TestHasOneOverrideReferences2(t *testing.T) { func TestHasOneOverrideReferences2(t *testing.T) {
type Profile struct { type Profile struct {
gorm.Model gorm.Model
Name string Name string
@ -518,7 +516,6 @@ func TestSameForeignKey(t *testing.T) {
} }
func TestBelongsToSameForeignKey(t *testing.T) { func TestBelongsToSameForeignKey(t *testing.T) {
type User struct { type User struct {
gorm.Model gorm.Model
Name string Name string

View File

@ -145,8 +145,7 @@ func TestParseSchemaWithAdvancedDataType(t *testing.T) {
} }
} }
type CustomizeTable struct { type CustomizeTable struct{}
}
func (CustomizeTable) TableName() string { func (CustomizeTable) TableName() string {
return "customize" return "customize"
@ -165,7 +164,6 @@ func TestCustomizeTableName(t *testing.T) {
func TestNestedModel(t *testing.T) { func TestNestedModel(t *testing.T) {
versionUser, err := schema.Parse(&VersionUser{}, &sync.Map{}, schema.NamingStrategy{}) versionUser, err := schema.Parse(&VersionUser{}, &sync.Map{}, schema.NamingStrategy{})
if err != nil { if err != nil {
t.Fatalf("failed to parse nested user, got error %v", err) t.Fatalf("failed to parse nested user, got error %v", err)
} }
@ -204,7 +202,6 @@ func TestEmbeddedStruct(t *testing.T) {
} }
cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, schema.NamingStrategy{}) cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, schema.NamingStrategy{})
if err != nil { if err != nil {
t.Fatalf("failed to parse embedded struct with primary key, got error %v", err) t.Fatalf("failed to parse embedded struct with primary key, got error %v", err)
} }
@ -273,7 +270,6 @@ func TestEmbeddedStructForCustomizedNamingStrategy(t *testing.T) {
} }
cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, CustomizedNamingStrategy{schema.NamingStrategy{}}) cropSchema, err := schema.Parse(&Corp{}, &sync.Map{}, CustomizedNamingStrategy{schema.NamingStrategy{}})
if err != nil { if err != nil {
t.Fatalf("failed to parse embedded struct with primary key, got error %v", err) t.Fatalf("failed to parse embedded struct with primary key, got error %v", err)
} }

View File

@ -328,7 +328,7 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []
conds = append(conds, clause.Eq{Column: i, Value: j}) conds = append(conds, clause.Eq{Column: i, Value: j})
} }
case map[string]string: case map[string]string:
var keys = make([]string, 0, len(v)) keys := make([]string, 0, len(v))
for i := range v { for i := range v {
keys = append(keys, i) keys = append(keys, i)
} }
@ -338,7 +338,7 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []
conds = append(conds, clause.Eq{Column: key, Value: v[key]}) conds = append(conds, clause.Eq{Column: key, Value: v[key]})
} }
case map[string]interface{}: case map[string]interface{}:
var keys = make([]string, 0, len(v)) keys := make([]string, 0, len(v))
for i := range v { for i := range v {
keys = append(keys, i) keys = append(keys, i)
} }

View File

@ -7,7 +7,7 @@ import (
) )
func TestBelongsToAssociation(t *testing.T) { func TestBelongsToAssociation(t *testing.T) {
var user = *GetUser("belongs-to", Config{Company: true, Manager: true}) user := *GetUser("belongs-to", Config{Company: true, Manager: true})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -31,8 +31,8 @@ func TestBelongsToAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Manager", 1, "") AssertAssociationCount(t, user, "Manager", 1, "")
// Append // Append
var company = Company{Name: "company-belongs-to-append"} company := Company{Name: "company-belongs-to-append"}
var manager = GetUser("manager-belongs-to-append", Config{}) manager := GetUser("manager-belongs-to-append", Config{})
if err := DB.Model(&user2).Association("Company").Append(&company); err != nil { if err := DB.Model(&user2).Association("Company").Append(&company); err != nil {
t.Fatalf("Error happened when append Company, got %v", err) t.Fatalf("Error happened when append Company, got %v", err)
@ -60,8 +60,8 @@ func TestBelongsToAssociation(t *testing.T) {
AssertAssociationCount(t, user2, "Manager", 1, "AfterAppend") AssertAssociationCount(t, user2, "Manager", 1, "AfterAppend")
// Replace // Replace
var company2 = Company{Name: "company-belongs-to-replace"} company2 := Company{Name: "company-belongs-to-replace"}
var manager2 = GetUser("manager-belongs-to-replace", Config{}) manager2 := GetUser("manager-belongs-to-replace", Config{})
if err := DB.Model(&user2).Association("Company").Replace(&company2); err != nil { if err := DB.Model(&user2).Association("Company").Replace(&company2); err != nil {
t.Fatalf("Error happened when replace Company, got %v", err) t.Fatalf("Error happened when replace Company, got %v", err)
@ -142,7 +142,7 @@ func TestBelongsToAssociation(t *testing.T) {
} }
func TestBelongsToAssociationForSlice(t *testing.T) { func TestBelongsToAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-belongs-to-1", Config{Company: true, Manager: true}), *GetUser("slice-belongs-to-1", Config{Company: true, Manager: true}),
*GetUser("slice-belongs-to-2", Config{Company: true, Manager: false}), *GetUser("slice-belongs-to-2", Config{Company: true, Manager: false}),
*GetUser("slice-belongs-to-3", Config{Company: true, Manager: true}), *GetUser("slice-belongs-to-3", Config{Company: true, Manager: true}),

View File

@ -7,7 +7,7 @@ import (
) )
func TestHasManyAssociation(t *testing.T) { func TestHasManyAssociation(t *testing.T) {
var user = *GetUser("hasmany", Config{Pets: 2}) user := *GetUser("hasmany", Config{Pets: 2})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -42,7 +42,7 @@ func TestHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Pets", 2, "") AssertAssociationCount(t, user, "Pets", 2, "")
// Append // Append
var pet = Pet{Name: "pet-has-many-append"} pet := Pet{Name: "pet-has-many-append"}
if err := DB.Model(&user2).Association("Pets").Append(&pet); err != nil { if err := DB.Model(&user2).Association("Pets").Append(&pet); err != nil {
t.Fatalf("Error happened when append account, got %v", err) t.Fatalf("Error happened when append account, got %v", err)
@ -57,14 +57,14 @@ func TestHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Pets", 3, "AfterAppend") AssertAssociationCount(t, user, "Pets", 3, "AfterAppend")
var pets2 = []Pet{{Name: "pet-has-many-append-1-1"}, {Name: "pet-has-many-append-1-1"}} pets2 := []Pet{{Name: "pet-has-many-append-1-1"}, {Name: "pet-has-many-append-1-1"}}
if err := DB.Model(&user2).Association("Pets").Append(&pets2); err != nil { if err := DB.Model(&user2).Association("Pets").Append(&pets2); err != nil {
t.Fatalf("Error happened when append pet, got %v", err) t.Fatalf("Error happened when append pet, got %v", err)
} }
for _, pet := range pets2 { for _, pet := range pets2 {
var pet = pet pet := pet
if pet.ID == 0 { if pet.ID == 0 {
t.Fatalf("Pet's ID should be created") t.Fatalf("Pet's ID should be created")
} }
@ -77,7 +77,7 @@ func TestHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Pets", 5, "AfterAppendSlice") AssertAssociationCount(t, user, "Pets", 5, "AfterAppendSlice")
// Replace // Replace
var pet2 = Pet{Name: "pet-has-many-replace"} pet2 := Pet{Name: "pet-has-many-replace"}
if err := DB.Model(&user2).Association("Pets").Replace(&pet2); err != nil { if err := DB.Model(&user2).Association("Pets").Replace(&pet2); err != nil {
t.Fatalf("Error happened when append pet, got %v", err) t.Fatalf("Error happened when append pet, got %v", err)
@ -119,7 +119,7 @@ func TestHasManyAssociation(t *testing.T) {
} }
func TestSingleTableHasManyAssociation(t *testing.T) { func TestSingleTableHasManyAssociation(t *testing.T) {
var user = *GetUser("hasmany", Config{Team: 2}) user := *GetUser("hasmany", Config{Team: 2})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -137,7 +137,7 @@ func TestSingleTableHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Team", 2, "") AssertAssociationCount(t, user, "Team", 2, "")
// Append // Append
var team = *GetUser("team", Config{}) team := *GetUser("team", Config{})
if err := DB.Model(&user2).Association("Team").Append(&team); err != nil { if err := DB.Model(&user2).Association("Team").Append(&team); err != nil {
t.Fatalf("Error happened when append account, got %v", err) t.Fatalf("Error happened when append account, got %v", err)
@ -152,14 +152,14 @@ func TestSingleTableHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Team", 3, "AfterAppend") AssertAssociationCount(t, user, "Team", 3, "AfterAppend")
var teams = []User{*GetUser("team-append-1", Config{}), *GetUser("team-append-2", Config{})} teams := []User{*GetUser("team-append-1", Config{}), *GetUser("team-append-2", Config{})}
if err := DB.Model(&user2).Association("Team").Append(&teams); err != nil { if err := DB.Model(&user2).Association("Team").Append(&teams); err != nil {
t.Fatalf("Error happened when append team, got %v", err) t.Fatalf("Error happened when append team, got %v", err)
} }
for _, team := range teams { for _, team := range teams {
var team = team team := team
if team.ID == 0 { if team.ID == 0 {
t.Fatalf("Team's ID should be created") t.Fatalf("Team's ID should be created")
} }
@ -172,7 +172,7 @@ func TestSingleTableHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Team", 5, "AfterAppendSlice") AssertAssociationCount(t, user, "Team", 5, "AfterAppendSlice")
// Replace // Replace
var team2 = *GetUser("team-replace", Config{}) team2 := *GetUser("team-replace", Config{})
if err := DB.Model(&user2).Association("Team").Replace(&team2); err != nil { if err := DB.Model(&user2).Association("Team").Replace(&team2); err != nil {
t.Fatalf("Error happened when append team, got %v", err) t.Fatalf("Error happened when append team, got %v", err)
@ -214,7 +214,7 @@ func TestSingleTableHasManyAssociation(t *testing.T) {
} }
func TestHasManyAssociationForSlice(t *testing.T) { func TestHasManyAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-hasmany-1", Config{Pets: 2}), *GetUser("slice-hasmany-1", Config{Pets: 2}),
*GetUser("slice-hasmany-2", Config{Pets: 0}), *GetUser("slice-hasmany-2", Config{Pets: 0}),
*GetUser("slice-hasmany-3", Config{Pets: 4}), *GetUser("slice-hasmany-3", Config{Pets: 4}),
@ -268,7 +268,7 @@ func TestHasManyAssociationForSlice(t *testing.T) {
} }
func TestSingleTableHasManyAssociationForSlice(t *testing.T) { func TestSingleTableHasManyAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-hasmany-1", Config{Team: 2}), *GetUser("slice-hasmany-1", Config{Team: 2}),
*GetUser("slice-hasmany-2", Config{Team: 0}), *GetUser("slice-hasmany-2", Config{Team: 0}),
*GetUser("slice-hasmany-3", Config{Team: 4}), *GetUser("slice-hasmany-3", Config{Team: 4}),
@ -324,7 +324,7 @@ func TestSingleTableHasManyAssociationForSlice(t *testing.T) {
} }
func TestPolymorphicHasManyAssociation(t *testing.T) { func TestPolymorphicHasManyAssociation(t *testing.T) {
var user = *GetUser("hasmany", Config{Toys: 2}) user := *GetUser("hasmany", Config{Toys: 2})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -342,7 +342,7 @@ func TestPolymorphicHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Toys", 2, "") AssertAssociationCount(t, user, "Toys", 2, "")
// Append // Append
var toy = Toy{Name: "toy-has-many-append"} toy := Toy{Name: "toy-has-many-append"}
if err := DB.Model(&user2).Association("Toys").Append(&toy); err != nil { if err := DB.Model(&user2).Association("Toys").Append(&toy); err != nil {
t.Fatalf("Error happened when append account, got %v", err) t.Fatalf("Error happened when append account, got %v", err)
@ -357,14 +357,14 @@ func TestPolymorphicHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Toys", 3, "AfterAppend") AssertAssociationCount(t, user, "Toys", 3, "AfterAppend")
var toys = []Toy{{Name: "toy-has-many-append-1-1"}, {Name: "toy-has-many-append-1-1"}} toys := []Toy{{Name: "toy-has-many-append-1-1"}, {Name: "toy-has-many-append-1-1"}}
if err := DB.Model(&user2).Association("Toys").Append(&toys); err != nil { if err := DB.Model(&user2).Association("Toys").Append(&toys); err != nil {
t.Fatalf("Error happened when append toy, got %v", err) t.Fatalf("Error happened when append toy, got %v", err)
} }
for _, toy := range toys { for _, toy := range toys {
var toy = toy toy := toy
if toy.ID == 0 { if toy.ID == 0 {
t.Fatalf("Toy's ID should be created") t.Fatalf("Toy's ID should be created")
} }
@ -377,7 +377,7 @@ func TestPolymorphicHasManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Toys", 5, "AfterAppendSlice") AssertAssociationCount(t, user, "Toys", 5, "AfterAppendSlice")
// Replace // Replace
var toy2 = Toy{Name: "toy-has-many-replace"} toy2 := Toy{Name: "toy-has-many-replace"}
if err := DB.Model(&user2).Association("Toys").Replace(&toy2); err != nil { if err := DB.Model(&user2).Association("Toys").Replace(&toy2); err != nil {
t.Fatalf("Error happened when append toy, got %v", err) t.Fatalf("Error happened when append toy, got %v", err)
@ -419,7 +419,7 @@ func TestPolymorphicHasManyAssociation(t *testing.T) {
} }
func TestPolymorphicHasManyAssociationForSlice(t *testing.T) { func TestPolymorphicHasManyAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-hasmany-1", Config{Toys: 2}), *GetUser("slice-hasmany-1", Config{Toys: 2}),
*GetUser("slice-hasmany-2", Config{Toys: 0}), *GetUser("slice-hasmany-2", Config{Toys: 0}),
*GetUser("slice-hasmany-3", Config{Toys: 4}), *GetUser("slice-hasmany-3", Config{Toys: 4}),

View File

@ -7,7 +7,7 @@ import (
) )
func TestHasOneAssociation(t *testing.T) { func TestHasOneAssociation(t *testing.T) {
var user = *GetUser("hasone", Config{Account: true}) user := *GetUser("hasone", Config{Account: true})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -25,7 +25,7 @@ func TestHasOneAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Account", 1, "") AssertAssociationCount(t, user, "Account", 1, "")
// Append // Append
var account = Account{Number: "account-has-one-append"} account := Account{Number: "account-has-one-append"}
if err := DB.Model(&user2).Association("Account").Append(&account); err != nil { if err := DB.Model(&user2).Association("Account").Append(&account); err != nil {
t.Fatalf("Error happened when append account, got %v", err) t.Fatalf("Error happened when append account, got %v", err)
@ -41,7 +41,7 @@ func TestHasOneAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Account", 1, "AfterAppend") AssertAssociationCount(t, user, "Account", 1, "AfterAppend")
// Replace // Replace
var account2 = Account{Number: "account-has-one-replace"} account2 := Account{Number: "account-has-one-replace"}
if err := DB.Model(&user2).Association("Account").Replace(&account2); err != nil { if err := DB.Model(&user2).Association("Account").Replace(&account2); err != nil {
t.Fatalf("Error happened when append Account, got %v", err) t.Fatalf("Error happened when append Account, got %v", err)
@ -84,7 +84,7 @@ func TestHasOneAssociation(t *testing.T) {
} }
func TestHasOneAssociationWithSelect(t *testing.T) { func TestHasOneAssociationWithSelect(t *testing.T) {
var user = *GetUser("hasone", Config{Account: true}) user := *GetUser("hasone", Config{Account: true})
DB.Omit("Account.Number").Create(&user) DB.Omit("Account.Number").Create(&user)
@ -98,7 +98,7 @@ func TestHasOneAssociationWithSelect(t *testing.T) {
} }
func TestHasOneAssociationForSlice(t *testing.T) { func TestHasOneAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-hasone-1", Config{Account: true}), *GetUser("slice-hasone-1", Config{Account: true}),
*GetUser("slice-hasone-2", Config{Account: false}), *GetUser("slice-hasone-2", Config{Account: false}),
*GetUser("slice-hasone-3", Config{Account: true}), *GetUser("slice-hasone-3", Config{Account: true}),
@ -139,7 +139,7 @@ func TestHasOneAssociationForSlice(t *testing.T) {
} }
func TestPolymorphicHasOneAssociation(t *testing.T) { func TestPolymorphicHasOneAssociation(t *testing.T) {
var pet = Pet{Name: "hasone", Toy: Toy{Name: "toy-has-one"}} pet := Pet{Name: "hasone", Toy: Toy{Name: "toy-has-one"}}
if err := DB.Create(&pet).Error; err != nil { if err := DB.Create(&pet).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -157,7 +157,7 @@ func TestPolymorphicHasOneAssociation(t *testing.T) {
AssertAssociationCount(t, pet, "Toy", 1, "") AssertAssociationCount(t, pet, "Toy", 1, "")
// Append // Append
var toy = Toy{Name: "toy-has-one-append"} toy := Toy{Name: "toy-has-one-append"}
if err := DB.Model(&pet2).Association("Toy").Append(&toy); err != nil { if err := DB.Model(&pet2).Association("Toy").Append(&toy); err != nil {
t.Fatalf("Error happened when append toy, got %v", err) t.Fatalf("Error happened when append toy, got %v", err)
@ -173,7 +173,7 @@ func TestPolymorphicHasOneAssociation(t *testing.T) {
AssertAssociationCount(t, pet, "Toy", 1, "AfterAppend") AssertAssociationCount(t, pet, "Toy", 1, "AfterAppend")
// Replace // Replace
var toy2 = Toy{Name: "toy-has-one-replace"} toy2 := Toy{Name: "toy-has-one-replace"}
if err := DB.Model(&pet2).Association("Toy").Replace(&toy2); err != nil { if err := DB.Model(&pet2).Association("Toy").Replace(&toy2); err != nil {
t.Fatalf("Error happened when append Toy, got %v", err) t.Fatalf("Error happened when append Toy, got %v", err)
@ -216,7 +216,7 @@ func TestPolymorphicHasOneAssociation(t *testing.T) {
} }
func TestPolymorphicHasOneAssociationForSlice(t *testing.T) { func TestPolymorphicHasOneAssociationForSlice(t *testing.T) {
var pets = []Pet{ pets := []Pet{
{Name: "hasone-1", Toy: Toy{Name: "toy-has-one"}}, {Name: "hasone-1", Toy: Toy{Name: "toy-has-one"}},
{Name: "hasone-2", Toy: Toy{}}, {Name: "hasone-2", Toy: Toy{}},
{Name: "hasone-3", Toy: Toy{Name: "toy-has-one"}}, {Name: "hasone-3", Toy: Toy{Name: "toy-has-one"}},

View File

@ -7,7 +7,7 @@ import (
) )
func TestMany2ManyAssociation(t *testing.T) { func TestMany2ManyAssociation(t *testing.T) {
var user = *GetUser("many2many", Config{Languages: 2}) user := *GetUser("many2many", Config{Languages: 2})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -26,7 +26,7 @@ func TestMany2ManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Languages", 2, "") AssertAssociationCount(t, user, "Languages", 2, "")
// Append // Append
var language = Language{Code: "language-many2many-append", Name: "language-many2many-append"} language := Language{Code: "language-many2many-append", Name: "language-many2many-append"}
DB.Create(&language) DB.Create(&language)
if err := DB.Model(&user2).Association("Languages").Append(&language); err != nil { if err := DB.Model(&user2).Association("Languages").Append(&language); err != nil {
@ -38,7 +38,7 @@ func TestMany2ManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Languages", 3, "AfterAppend") AssertAssociationCount(t, user, "Languages", 3, "AfterAppend")
var languages = []Language{ languages := []Language{
{Code: "language-many2many-append-1-1", Name: "language-many2many-append-1-1"}, {Code: "language-many2many-append-1-1", Name: "language-many2many-append-1-1"},
{Code: "language-many2many-append-2-1", Name: "language-many2many-append-2-1"}, {Code: "language-many2many-append-2-1", Name: "language-many2many-append-2-1"},
} }
@ -55,7 +55,7 @@ func TestMany2ManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Languages", 5, "AfterAppendSlice") AssertAssociationCount(t, user, "Languages", 5, "AfterAppendSlice")
// Replace // Replace
var language2 = Language{Code: "language-many2many-replace", Name: "language-many2many-replace"} language2 := Language{Code: "language-many2many-replace", Name: "language-many2many-replace"}
DB.Create(&language2) DB.Create(&language2)
if err := DB.Model(&user2).Association("Languages").Replace(&language2); err != nil { if err := DB.Model(&user2).Association("Languages").Replace(&language2); err != nil {
@ -94,7 +94,7 @@ func TestMany2ManyAssociation(t *testing.T) {
} }
func TestMany2ManyOmitAssociations(t *testing.T) { func TestMany2ManyOmitAssociations(t *testing.T) {
var user = *GetUser("many2many_omit_associations", Config{Languages: 2}) user := *GetUser("many2many_omit_associations", Config{Languages: 2})
if err := DB.Omit("Languages.*").Create(&user).Error; err == nil { if err := DB.Omit("Languages.*").Create(&user).Error; err == nil {
t.Fatalf("should raise error when create users without languages reference") t.Fatalf("should raise error when create users without languages reference")
@ -114,14 +114,14 @@ func TestMany2ManyOmitAssociations(t *testing.T) {
t.Errorf("languages count should be %v, but got %v", 2, len(languages)) t.Errorf("languages count should be %v, but got %v", 2, len(languages))
} }
var newLang = Language{Code: "omitmany2many", Name: "omitmany2many"} newLang := Language{Code: "omitmany2many", Name: "omitmany2many"}
if err := DB.Model(&user).Omit("Languages.*").Association("Languages").Replace(&newLang); err == nil { if err := DB.Model(&user).Omit("Languages.*").Association("Languages").Replace(&newLang); err == nil {
t.Errorf("should failed to insert languages due to constraint failed, error: %v", err) t.Errorf("should failed to insert languages due to constraint failed, error: %v", err)
} }
} }
func TestMany2ManyAssociationForSlice(t *testing.T) { func TestMany2ManyAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-many2many-1", Config{Languages: 2}), *GetUser("slice-many2many-1", Config{Languages: 2}),
*GetUser("slice-many2many-2", Config{Languages: 0}), *GetUser("slice-many2many-2", Config{Languages: 0}),
*GetUser("slice-many2many-3", Config{Languages: 4}), *GetUser("slice-many2many-3", Config{Languages: 4}),
@ -139,11 +139,11 @@ func TestMany2ManyAssociationForSlice(t *testing.T) {
} }
// Append // Append
var languages1 = []Language{ languages1 := []Language{
{Code: "language-many2many-append-1", Name: "language-many2many-append-1"}, {Code: "language-many2many-append-1", Name: "language-many2many-append-1"},
} }
var languages2 = []Language{} languages2 := []Language{}
var languages3 = []Language{ languages3 := []Language{
{Code: "language-many2many-append-3-1", Name: "language-many2many-append-3-1"}, {Code: "language-many2many-append-3-1", Name: "language-many2many-append-3-1"},
{Code: "language-many2many-append-3-2", Name: "language-many2many-append-3-2"}, {Code: "language-many2many-append-3-2", Name: "language-many2many-append-3-2"},
} }
@ -191,7 +191,7 @@ func TestMany2ManyAssociationForSlice(t *testing.T) {
} }
func TestSingleTableMany2ManyAssociation(t *testing.T) { func TestSingleTableMany2ManyAssociation(t *testing.T) {
var user = *GetUser("many2many", Config{Friends: 2}) user := *GetUser("many2many", Config{Friends: 2})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -210,7 +210,7 @@ func TestSingleTableMany2ManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Friends", 2, "") AssertAssociationCount(t, user, "Friends", 2, "")
// Append // Append
var friend = *GetUser("friend", Config{}) friend := *GetUser("friend", Config{})
if err := DB.Model(&user2).Association("Friends").Append(&friend); err != nil { if err := DB.Model(&user2).Association("Friends").Append(&friend); err != nil {
t.Fatalf("Error happened when append account, got %v", err) t.Fatalf("Error happened when append account, got %v", err)
@ -221,7 +221,7 @@ func TestSingleTableMany2ManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Friends", 3, "AfterAppend") AssertAssociationCount(t, user, "Friends", 3, "AfterAppend")
var friends = []*User{GetUser("friend-append-1", Config{}), GetUser("friend-append-2", Config{})} friends := []*User{GetUser("friend-append-1", Config{}), GetUser("friend-append-2", Config{})}
if err := DB.Model(&user2).Association("Friends").Append(&friends); err != nil { if err := DB.Model(&user2).Association("Friends").Append(&friends); err != nil {
t.Fatalf("Error happened when append friend, got %v", err) t.Fatalf("Error happened when append friend, got %v", err)
@ -234,7 +234,7 @@ func TestSingleTableMany2ManyAssociation(t *testing.T) {
AssertAssociationCount(t, user, "Friends", 5, "AfterAppendSlice") AssertAssociationCount(t, user, "Friends", 5, "AfterAppendSlice")
// Replace // Replace
var friend2 = *GetUser("friend-replace-2", Config{}) friend2 := *GetUser("friend-replace-2", Config{})
if err := DB.Model(&user2).Association("Friends").Replace(&friend2); err != nil { if err := DB.Model(&user2).Association("Friends").Replace(&friend2); err != nil {
t.Fatalf("Error happened when append friend, got %v", err) t.Fatalf("Error happened when append friend, got %v", err)
@ -272,7 +272,7 @@ func TestSingleTableMany2ManyAssociation(t *testing.T) {
} }
func TestSingleTableMany2ManyAssociationForSlice(t *testing.T) { func TestSingleTableMany2ManyAssociationForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice-many2many-1", Config{Team: 2}), *GetUser("slice-many2many-1", Config{Team: 2}),
*GetUser("slice-many2many-2", Config{Team: 0}), *GetUser("slice-many2many-2", Config{Team: 0}),
*GetUser("slice-many2many-3", Config{Team: 4}), *GetUser("slice-many2many-3", Config{Team: 4}),
@ -290,17 +290,17 @@ func TestSingleTableMany2ManyAssociationForSlice(t *testing.T) {
} }
// Append // Append
var teams1 = []User{*GetUser("friend-append-1", Config{})} teams1 := []User{*GetUser("friend-append-1", Config{})}
var teams2 = []User{} teams2 := []User{}
var teams3 = []*User{GetUser("friend-append-3-1", Config{}), GetUser("friend-append-3-2", Config{})} teams3 := []*User{GetUser("friend-append-3-1", Config{}), GetUser("friend-append-3-2", Config{})}
DB.Model(&users).Association("Team").Append(&teams1, &teams2, &teams3) DB.Model(&users).Association("Team").Append(&teams1, &teams2, &teams3)
AssertAssociationCount(t, users, "Team", 9, "After Append") AssertAssociationCount(t, users, "Team", 9, "After Append")
var teams2_1 = []User{*GetUser("friend-replace-1", Config{}), *GetUser("friend-replace-2", Config{})} teams2_1 := []User{*GetUser("friend-replace-1", Config{}), *GetUser("friend-replace-2", Config{})}
var teams2_2 = []User{*GetUser("friend-replace-2-1", Config{}), *GetUser("friend-replace-2-2", Config{})} teams2_2 := []User{*GetUser("friend-replace-2-1", Config{}), *GetUser("friend-replace-2-2", Config{})}
var teams2_3 = GetUser("friend-replace-3-1", Config{}) teams2_3 := GetUser("friend-replace-3-1", Config{})
// Replace // Replace
DB.Model(&users).Association("Team").Replace(&teams2_1, &teams2_2, teams2_3) DB.Model(&users).Association("Team").Replace(&teams2_1, &teams2_2, teams2_3)

View File

@ -27,7 +27,7 @@ func AssertAssociationCount(t *testing.T, data interface{}, name string, result
} }
func TestInvalidAssociation(t *testing.T) { func TestInvalidAssociation(t *testing.T) {
var user = *GetUser("invalid", Config{Company: true, Manager: true}) user := *GetUser("invalid", Config{Company: true, Manager: true})
if err := DB.Model(&user).Association("Invalid").Find(&user.Company).Error; err == nil { if err := DB.Model(&user).Association("Invalid").Find(&user.Company).Error; err == nil {
t.Fatalf("should return errors for invalid association, but got nil") t.Fatalf("should return errors for invalid association, but got nil")
} }
@ -189,7 +189,6 @@ func TestFullSaveAssociations(t *testing.T) {
err := DB. err := DB.
Session(&gorm.Session{FullSaveAssociations: true}). Session(&gorm.Session{FullSaveAssociations: true}).
Create(coupon).Error Create(coupon).Error
if err != nil { if err != nil {
t.Errorf("Failed, got error: %v", err) t.Errorf("Failed, got error: %v", err)
} }

View File

@ -7,7 +7,7 @@ import (
) )
func BenchmarkCreate(b *testing.B) { func BenchmarkCreate(b *testing.B) {
var user = *GetUser("bench", Config{}) user := *GetUser("bench", Config{})
for x := 0; x < b.N; x++ { for x := 0; x < b.N; x++ {
user.ID = 0 user.ID = 0
@ -16,7 +16,7 @@ func BenchmarkCreate(b *testing.B) {
} }
func BenchmarkFind(b *testing.B) { func BenchmarkFind(b *testing.B) {
var user = *GetUser("find", Config{}) user := *GetUser("find", Config{})
DB.Create(&user) DB.Create(&user)
for x := 0; x < b.N; x++ { for x := 0; x < b.N; x++ {
@ -25,7 +25,7 @@ func BenchmarkFind(b *testing.B) {
} }
func BenchmarkUpdate(b *testing.B) { func BenchmarkUpdate(b *testing.B) {
var user = *GetUser("find", Config{}) user := *GetUser("find", Config{})
DB.Create(&user) DB.Create(&user)
for x := 0; x < b.N; x++ { for x := 0; x < b.N; x++ {
@ -34,7 +34,7 @@ func BenchmarkUpdate(b *testing.B) {
} }
func BenchmarkDelete(b *testing.B) { func BenchmarkDelete(b *testing.B) {
var user = *GetUser("find", Config{}) user := *GetUser("find", Config{})
for x := 0; x < b.N; x++ { for x := 0; x < b.N; x++ {
user.ID = 0 user.ID = 0

View File

@ -87,7 +87,7 @@ func TestCount(t *testing.T) {
t.Fatalf(fmt.Sprintf("Count should work, but got err %v", err)) t.Fatalf(fmt.Sprintf("Count should work, but got err %v", err))
} }
expects := []User{User{Name: "main"}, {Name: "other"}, {Name: "other"}} expects := []User{{Name: "main"}, {Name: "other"}, {Name: "other"}}
sort.SliceStable(users, func(i, j int) bool { sort.SliceStable(users, func(i, j int) bool {
return strings.Compare(users[i].Name, users[j].Name) < 0 return strings.Compare(users[i].Name, users[j].Name) < 0
}) })
@ -101,7 +101,7 @@ func TestCount(t *testing.T) {
t.Fatalf(fmt.Sprintf("Count should work, but got err %v", err)) t.Fatalf(fmt.Sprintf("Count should work, but got err %v", err))
} }
expects = []User{User{Name: "main", Age: 18}, {Name: "other", Age: 18}, {Name: "other", Age: 18}} expects = []User{{Name: "main", Age: 18}, {Name: "other", Age: 18}, {Name: "other", Age: 18}}
sort.SliceStable(users, func(i, j int) bool { sort.SliceStable(users, func(i, j int) bool {
return strings.Compare(users[i].Name, users[j].Name) < 0 return strings.Compare(users[i].Name, users[j].Name) < 0
}) })
@ -115,7 +115,7 @@ func TestCount(t *testing.T) {
t.Fatalf("Count should work, but got err %v", err) t.Fatalf("Count should work, but got err %v", err)
} }
expects = []User{User{Name: "count-1", Age: 1}, {Name: "count-2", Age: 1}, {Name: "count-3", Age: 1}} expects = []User{{Name: "count-1", Age: 1}, {Name: "count-2", Age: 1}, {Name: "count-3", Age: 1}}
sort.SliceStable(users, func(i, j int) bool { sort.SliceStable(users, func(i, j int) bool {
return strings.Compare(users[i].Name, users[j].Name) < 0 return strings.Compare(users[i].Name, users[j].Name) < 0
}) })
@ -144,5 +144,4 @@ func TestCount(t *testing.T) {
if err := DB.Model(&User{}).Where("name = ?", "count-4").Group("name").Count(&count11).Error; err != nil || count11 != 1 { if err := DB.Model(&User{}).Where("name = ?", "count-4").Group("name").Count(&count11).Error; err != nil || count11 != 1 {
t.Fatalf("Count should be 3, but got count: %v err %v", count11, err) t.Fatalf("Count should be 3, but got count: %v err %v", count11, err)
} }
} }

View File

@ -7,13 +7,14 @@ import (
"time" "time"
"github.com/jinzhu/now" "github.com/jinzhu/now"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
. "gorm.io/gorm/utils/tests" . "gorm.io/gorm/utils/tests"
) )
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
var user = *GetUser("create", Config{}) user := *GetUser("create", Config{})
if results := DB.Create(&user); results.Error != nil { if results := DB.Create(&user); results.Error != nil {
t.Fatalf("errors happened when create: %v", results.Error) t.Fatalf("errors happened when create: %v", results.Error)
@ -139,7 +140,7 @@ func TestCreateFromMap(t *testing.T) {
} }
func TestCreateWithAssociations(t *testing.T) { func TestCreateWithAssociations(t *testing.T) {
var user = *GetUser("create_with_associations", Config{ user := *GetUser("create_with_associations", Config{
Account: true, Account: true,
Pets: 2, Pets: 2,
Toys: 3, Toys: 3,
@ -223,7 +224,7 @@ func TestBulkCreatePtrDataWithAssociations(t *testing.T) {
func TestPolymorphicHasOne(t *testing.T) { func TestPolymorphicHasOne(t *testing.T) {
t.Run("Struct", func(t *testing.T) { t.Run("Struct", func(t *testing.T) {
var pet = Pet{ pet := Pet{
Name: "PolymorphicHasOne", Name: "PolymorphicHasOne",
Toy: Toy{Name: "Toy-PolymorphicHasOne"}, Toy: Toy{Name: "Toy-PolymorphicHasOne"},
} }
@ -240,7 +241,7 @@ func TestPolymorphicHasOne(t *testing.T) {
}) })
t.Run("Slice", func(t *testing.T) { t.Run("Slice", func(t *testing.T) {
var pets = []Pet{{ pets := []Pet{{
Name: "PolymorphicHasOne-Slice-1", Name: "PolymorphicHasOne-Slice-1",
Toy: Toy{Name: "Toy-PolymorphicHasOne-Slice-1"}, Toy: Toy{Name: "Toy-PolymorphicHasOne-Slice-1"},
}, { }, {
@ -269,7 +270,7 @@ func TestPolymorphicHasOne(t *testing.T) {
}) })
t.Run("SliceOfPtr", func(t *testing.T) { t.Run("SliceOfPtr", func(t *testing.T) {
var pets = []*Pet{{ pets := []*Pet{{
Name: "PolymorphicHasOne-Slice-1", Name: "PolymorphicHasOne-Slice-1",
Toy: Toy{Name: "Toy-PolymorphicHasOne-Slice-1"}, Toy: Toy{Name: "Toy-PolymorphicHasOne-Slice-1"},
}, { }, {
@ -290,7 +291,7 @@ func TestPolymorphicHasOne(t *testing.T) {
}) })
t.Run("Array", func(t *testing.T) { t.Run("Array", func(t *testing.T) {
var pets = [...]Pet{{ pets := [...]Pet{{
Name: "PolymorphicHasOne-Array-1", Name: "PolymorphicHasOne-Array-1",
Toy: Toy{Name: "Toy-PolymorphicHasOne-Array-1"}, Toy: Toy{Name: "Toy-PolymorphicHasOne-Array-1"},
}, { }, {
@ -311,7 +312,7 @@ func TestPolymorphicHasOne(t *testing.T) {
}) })
t.Run("ArrayPtr", func(t *testing.T) { t.Run("ArrayPtr", func(t *testing.T) {
var pets = [...]*Pet{{ pets := [...]*Pet{{
Name: "PolymorphicHasOne-Array-1", Name: "PolymorphicHasOne-Array-1",
Toy: Toy{Name: "Toy-PolymorphicHasOne-Array-1"}, Toy: Toy{Name: "Toy-PolymorphicHasOne-Array-1"},
}, { }, {
@ -348,12 +349,12 @@ func TestCreateEmptyStruct(t *testing.T) {
} }
func TestCreateEmptySlice(t *testing.T) { func TestCreateEmptySlice(t *testing.T) {
var data = []User{} data := []User{}
if err := DB.Create(&data).Error; err != gorm.ErrEmptySlice { if err := DB.Create(&data).Error; err != gorm.ErrEmptySlice {
t.Errorf("no data should be created, got %v", err) t.Errorf("no data should be created, got %v", err)
} }
var sliceMap = []map[string]interface{}{} sliceMap := []map[string]interface{}{}
if err := DB.Model(&User{}).Create(&sliceMap).Error; err != gorm.ErrEmptySlice { if err := DB.Model(&User{}).Create(&sliceMap).Error; err != gorm.ErrEmptySlice {
t.Errorf("no data should be created, got %v", err) t.Errorf("no data should be created, got %v", err)
} }

View File

@ -23,7 +23,7 @@ func TestDefaultValue(t *testing.T) {
t.Fatalf("Failed to migrate with default value, got error: %v", err) t.Fatalf("Failed to migrate with default value, got error: %v", err)
} }
var harumph = Harumph{Email: "hello@gorm.io"} harumph := Harumph{Email: "hello@gorm.io"}
if err := DB.Create(&harumph).Error; err != nil { if err := DB.Create(&harumph).Error; err != nil {
t.Fatalf("Failed to create data with default value, got error: %v", err) t.Fatalf("Failed to create data with default value, got error: %v", err)
} else if harumph.Name != "foo" || harumph.Name2 != "foo" || harumph.Name3 != "" || harumph.Age != 18 || !harumph.Enabled { } else if harumph.Name != "foo" || harumph.Name2 != "foo" || harumph.Name3 != "" || harumph.Age != 18 || !harumph.Enabled {

View File

@ -10,7 +10,7 @@ import (
) )
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
var users = []User{*GetUser("delete", Config{}), *GetUser("delete", Config{}), *GetUser("delete", Config{})} users := []User{*GetUser("delete", Config{}), *GetUser("delete", Config{}), *GetUser("delete", Config{})}
if err := DB.Create(&users).Error; err != nil { if err := DB.Create(&users).Error; err != nil {
t.Errorf("errors happened when create: %v", err) t.Errorf("errors happened when create: %v", err)

View File

@ -9,7 +9,7 @@ import (
) )
func TestDistinct(t *testing.T) { func TestDistinct(t *testing.T) {
var users = []User{ users := []User{
*GetUser("distinct", Config{}), *GetUser("distinct", Config{}),
*GetUser("distinct", Config{}), *GetUser("distinct", Config{}),
*GetUser("distinct", Config{}), *GetUser("distinct", Config{}),

View File

@ -7,7 +7,7 @@ import (
) )
func TestGroupBy(t *testing.T) { func TestGroupBy(t *testing.T) {
var users = []User{{ users := []User{{
Name: "groupby", Name: "groupby",
Age: 10, Age: 10,
Birthday: Now(), Birthday: Now(),
@ -67,7 +67,7 @@ func TestGroupBy(t *testing.T) {
t.Errorf("name should be groupby, but got %v, total should be 660, but got %v", name, total) t.Errorf("name should be groupby, but got %v, total should be 660, but got %v", name, total)
} }
var result = struct { result := struct {
Name string Name string
Total int64 Total int64
}{} }{}

View File

@ -57,7 +57,7 @@ func TestJoinsForSlice(t *testing.T) {
} }
func TestJoinConds(t *testing.T) { func TestJoinConds(t *testing.T) {
var user = *GetUser("joins-conds", Config{Account: true, Pets: 3}) user := *GetUser("joins-conds", Config{Account: true, Pets: 3})
DB.Save(&user) DB.Save(&user)
var users1 []User var users1 []User
@ -111,7 +111,7 @@ func TestJoinConds(t *testing.T) {
} }
func TestJoinOn(t *testing.T) { func TestJoinOn(t *testing.T) {
var user = *GetUser("joins-on", Config{Pets: 2}) user := *GetUser("joins-on", Config{Pets: 2})
DB.Save(&user) DB.Save(&user)
var user1 User var user1 User

View File

@ -174,7 +174,6 @@ func TestSmartMigrateColumn(t *testing.T) {
} }
} }
} }
} }
func TestMigrateWithColumnComment(t *testing.T) { func TestMigrateWithColumnComment(t *testing.T) {

View File

@ -71,7 +71,7 @@ func TestManyToManyWithMultiPrimaryKeys(t *testing.T) {
} }
// Append // Append
var tag3 = &Tag{Locale: "ZH", Value: "tag3"} tag3 := &Tag{Locale: "ZH", Value: "tag3"}
DB.Model(&blog).Association("Tags").Append([]*Tag{tag3}) DB.Model(&blog).Association("Tags").Append([]*Tag{tag3})
if !compareTags(blog.Tags, []string{"tag1", "tag2", "tag3"}) { if !compareTags(blog.Tags, []string{"tag1", "tag2", "tag3"}) {
@ -95,8 +95,8 @@ func TestManyToManyWithMultiPrimaryKeys(t *testing.T) {
} }
// Replace // Replace
var tag5 = &Tag{Locale: "ZH", Value: "tag5"} tag5 := &Tag{Locale: "ZH", Value: "tag5"}
var tag6 = &Tag{Locale: "ZH", Value: "tag6"} tag6 := &Tag{Locale: "ZH", Value: "tag6"}
DB.Model(&blog).Association("Tags").Replace(tag5, tag6) DB.Model(&blog).Association("Tags").Replace(tag5, tag6)
var tags2 []Tag var tags2 []Tag
DB.Model(&blog).Association("Tags").Find(&tags2) DB.Model(&blog).Association("Tags").Find(&tags2)
@ -170,7 +170,7 @@ func TestManyToManyWithCustomizedForeignKeys(t *testing.T) {
} }
// Append // Append
var tag3 = &Tag{Locale: "ZH", Value: "tag3"} tag3 := &Tag{Locale: "ZH", Value: "tag3"}
DB.Model(&blog).Association("SharedTags").Append([]*Tag{tag3}) DB.Model(&blog).Association("SharedTags").Append([]*Tag{tag3})
if !compareTags(blog.SharedTags, []string{"tag1", "tag2", "tag3"}) { if !compareTags(blog.SharedTags, []string{"tag1", "tag2", "tag3"}) {
t.Fatalf("Blog should has three tags after Append") t.Fatalf("Blog should has three tags after Append")
@ -201,7 +201,7 @@ func TestManyToManyWithCustomizedForeignKeys(t *testing.T) {
t.Fatalf("Preload many2many relations") t.Fatalf("Preload many2many relations")
} }
var tag4 = &Tag{Locale: "ZH", Value: "tag4"} tag4 := &Tag{Locale: "ZH", Value: "tag4"}
DB.Model(&blog2).Association("SharedTags").Append(tag4) DB.Model(&blog2).Association("SharedTags").Append(tag4)
DB.Model(&blog).Association("SharedTags").Find(&tags) DB.Model(&blog).Association("SharedTags").Find(&tags)
@ -215,8 +215,8 @@ func TestManyToManyWithCustomizedForeignKeys(t *testing.T) {
} }
// Replace // Replace
var tag5 = &Tag{Locale: "ZH", Value: "tag5"} tag5 := &Tag{Locale: "ZH", Value: "tag5"}
var tag6 = &Tag{Locale: "ZH", Value: "tag6"} tag6 := &Tag{Locale: "ZH", Value: "tag6"}
DB.Model(&blog2).Association("SharedTags").Replace(tag5, tag6) DB.Model(&blog2).Association("SharedTags").Replace(tag5, tag6)
var tags2 []Tag var tags2 []Tag
DB.Model(&blog).Association("SharedTags").Find(&tags2) DB.Model(&blog).Association("SharedTags").Find(&tags2)
@ -291,7 +291,7 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) {
DB.Create(&blog2) DB.Create(&blog2)
// Append // Append
var tag3 = &Tag{Locale: "ZH", Value: "tag3"} tag3 := &Tag{Locale: "ZH", Value: "tag3"}
DB.Model(&blog).Association("LocaleTags").Append([]*Tag{tag3}) DB.Model(&blog).Association("LocaleTags").Append([]*Tag{tag3})
if !compareTags(blog.LocaleTags, []string{"tag1", "tag2", "tag3"}) { if !compareTags(blog.LocaleTags, []string{"tag1", "tag2", "tag3"}) {
t.Fatalf("Blog should has three tags after Append") t.Fatalf("Blog should has three tags after Append")
@ -322,7 +322,7 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) {
t.Fatalf("Preload many2many relations") t.Fatalf("Preload many2many relations")
} }
var tag4 = &Tag{Locale: "ZH", Value: "tag4"} tag4 := &Tag{Locale: "ZH", Value: "tag4"}
DB.Model(&blog2).Association("LocaleTags").Append(tag4) DB.Model(&blog2).Association("LocaleTags").Append(tag4)
DB.Model(&blog).Association("LocaleTags").Find(&tags) DB.Model(&blog).Association("LocaleTags").Find(&tags)
@ -336,8 +336,8 @@ func TestManyToManyWithCustomizedForeignKeys2(t *testing.T) {
} }
// Replace // Replace
var tag5 = &Tag{Locale: "ZH", Value: "tag5"} tag5 := &Tag{Locale: "ZH", Value: "tag5"}
var tag6 = &Tag{Locale: "ZH", Value: "tag6"} tag6 := &Tag{Locale: "ZH", Value: "tag6"}
DB.Model(&blog2).Association("LocaleTags").Replace(tag5, tag6) DB.Model(&blog2).Association("LocaleTags").Replace(tag5, tag6)
var tags2 []Tag var tags2 []Tag

View File

@ -5,6 +5,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/lib/pq" "github.com/lib/pq"
"gorm.io/gorm" "gorm.io/gorm"
) )

View File

@ -14,7 +14,7 @@ import (
) )
func TestPreloadWithAssociations(t *testing.T) { func TestPreloadWithAssociations(t *testing.T) {
var user = *GetUser("preload_with_associations", Config{ user := *GetUser("preload_with_associations", Config{
Account: true, Account: true,
Pets: 2, Pets: 2,
Toys: 3, Toys: 3,
@ -35,7 +35,7 @@ func TestPreloadWithAssociations(t *testing.T) {
DB.Preload(clause.Associations).Find(&user2, "id = ?", user.ID) DB.Preload(clause.Associations).Find(&user2, "id = ?", user.ID)
CheckUser(t, user2, user) CheckUser(t, user2, user)
var user3 = *GetUser("preload_with_associations_new", Config{ user3 := *GetUser("preload_with_associations_new", Config{
Account: true, Account: true,
Pets: 2, Pets: 2,
Toys: 3, Toys: 3,
@ -51,7 +51,7 @@ func TestPreloadWithAssociations(t *testing.T) {
} }
func TestNestedPreload(t *testing.T) { func TestNestedPreload(t *testing.T) {
var user = *GetUser("nested_preload", Config{Pets: 2}) user := *GetUser("nested_preload", Config{Pets: 2})
for idx, pet := range user.Pets { for idx, pet := range user.Pets {
pet.Toy = Toy{Name: "toy_nested_preload_" + strconv.Itoa(idx+1)} pet.Toy = Toy{Name: "toy_nested_preload_" + strconv.Itoa(idx+1)}
@ -75,7 +75,7 @@ func TestNestedPreload(t *testing.T) {
} }
func TestNestedPreloadForSlice(t *testing.T) { func TestNestedPreloadForSlice(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice_nested_preload_1", Config{Pets: 2}), *GetUser("slice_nested_preload_1", Config{Pets: 2}),
*GetUser("slice_nested_preload_2", Config{Pets: 0}), *GetUser("slice_nested_preload_2", Config{Pets: 0}),
*GetUser("slice_nested_preload_3", Config{Pets: 3}), *GetUser("slice_nested_preload_3", Config{Pets: 3}),
@ -105,7 +105,7 @@ func TestNestedPreloadForSlice(t *testing.T) {
} }
func TestPreloadWithConds(t *testing.T) { func TestPreloadWithConds(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice_nested_preload_1", Config{Account: true}), *GetUser("slice_nested_preload_1", Config{Account: true}),
*GetUser("slice_nested_preload_2", Config{Account: false}), *GetUser("slice_nested_preload_2", Config{Account: false}),
*GetUser("slice_nested_preload_3", Config{Account: true}), *GetUser("slice_nested_preload_3", Config{Account: true}),
@ -163,7 +163,7 @@ func TestPreloadWithConds(t *testing.T) {
} }
func TestNestedPreloadWithConds(t *testing.T) { func TestNestedPreloadWithConds(t *testing.T) {
var users = []User{ users := []User{
*GetUser("slice_nested_preload_1", Config{Pets: 2}), *GetUser("slice_nested_preload_1", Config{Pets: 2}),
*GetUser("slice_nested_preload_2", Config{Pets: 0}), *GetUser("slice_nested_preload_2", Config{Pets: 0}),
*GetUser("slice_nested_preload_3", Config{Pets: 3}), *GetUser("slice_nested_preload_3", Config{Pets: 3}),
@ -213,7 +213,7 @@ func TestNestedPreloadWithConds(t *testing.T) {
} }
func TestPreloadEmptyData(t *testing.T) { func TestPreloadEmptyData(t *testing.T) {
var user = *GetUser("user_without_associations", Config{}) user := *GetUser("user_without_associations", Config{})
DB.Create(&user) DB.Create(&user)
DB.Preload("Team").Preload("Languages").Preload("Friends").First(&user, "name = ?", user.Name) DB.Preload("Team").Preload("Languages").Preload("Friends").First(&user, "name = ?", user.Name)

View File

@ -17,7 +17,7 @@ import (
) )
func TestFind(t *testing.T) { func TestFind(t *testing.T) {
var users = []User{ users := []User{
*GetUser("find", Config{}), *GetUser("find", Config{}),
*GetUser("find", Config{}), *GetUser("find", Config{}),
*GetUser("find", Config{}), *GetUser("find", Config{}),
@ -57,7 +57,7 @@ func TestFind(t *testing.T) {
} }
t.Run("FirstMap", func(t *testing.T) { t.Run("FirstMap", func(t *testing.T) {
var first = map[string]interface{}{} first := map[string]interface{}{}
if err := DB.Model(&User{}).Where("name = ?", "find").First(first).Error; err != nil { if err := DB.Model(&User{}).Where("name = ?", "find").First(first).Error; err != nil {
t.Errorf("errors happened when query first: %v", err) t.Errorf("errors happened when query first: %v", err)
} else { } else {
@ -88,7 +88,7 @@ func TestFind(t *testing.T) {
}) })
t.Run("FirstMapWithTable", func(t *testing.T) { t.Run("FirstMapWithTable", func(t *testing.T) {
var first = map[string]interface{}{} first := map[string]interface{}{}
if err := DB.Table("users").Where("name = ?", "find").Find(first).Error; err != nil { if err := DB.Table("users").Where("name = ?", "find").Find(first).Error; err != nil {
t.Errorf("errors happened when query first: %v", err) t.Errorf("errors happened when query first: %v", err)
} else { } else {
@ -120,7 +120,7 @@ func TestFind(t *testing.T) {
}) })
t.Run("FirstPtrMap", func(t *testing.T) { t.Run("FirstPtrMap", func(t *testing.T) {
var first = map[string]interface{}{} first := map[string]interface{}{}
if err := DB.Model(&User{}).Where("name = ?", "find").First(&first).Error; err != nil { if err := DB.Model(&User{}).Where("name = ?", "find").First(&first).Error; err != nil {
t.Errorf("errors happened when query first: %v", err) t.Errorf("errors happened when query first: %v", err)
} else { } else {
@ -135,7 +135,7 @@ func TestFind(t *testing.T) {
}) })
t.Run("FirstSliceOfMap", func(t *testing.T) { t.Run("FirstSliceOfMap", func(t *testing.T) {
var allMap = []map[string]interface{}{} allMap := []map[string]interface{}{}
if err := DB.Model(&User{}).Where("name = ?", "find").Find(&allMap).Error; err != nil { if err := DB.Model(&User{}).Where("name = ?", "find").Find(&allMap).Error; err != nil {
t.Errorf("errors happened when query find: %v", err) t.Errorf("errors happened when query find: %v", err)
} else { } else {
@ -170,7 +170,7 @@ func TestFind(t *testing.T) {
}) })
t.Run("FindSliceOfMapWithTable", func(t *testing.T) { t.Run("FindSliceOfMapWithTable", func(t *testing.T) {
var allMap = []map[string]interface{}{} allMap := []map[string]interface{}{}
if err := DB.Table("users").Where("name = ?", "find").Find(&allMap).Error; err != nil { if err := DB.Table("users").Where("name = ?", "find").Find(&allMap).Error; err != nil {
t.Errorf("errors happened when query find: %v", err) t.Errorf("errors happened when query find: %v", err)
} else { } else {
@ -241,7 +241,7 @@ func TestQueryWithAssociation(t *testing.T) {
} }
func TestFindInBatches(t *testing.T) { func TestFindInBatches(t *testing.T) {
var users = []User{ users := []User{
*GetUser("find_in_batches", Config{}), *GetUser("find_in_batches", Config{}),
*GetUser("find_in_batches", Config{}), *GetUser("find_in_batches", Config{}),
*GetUser("find_in_batches", Config{}), *GetUser("find_in_batches", Config{}),
@ -297,7 +297,7 @@ func TestFindInBatchesWithError(t *testing.T) {
t.Skip("skip sqlserver due to it will raise data race for invalid sql") t.Skip("skip sqlserver due to it will raise data race for invalid sql")
} }
var users = []User{ users := []User{
*GetUser("find_in_batches_with_error", Config{}), *GetUser("find_in_batches_with_error", Config{}),
*GetUser("find_in_batches_with_error", Config{}), *GetUser("find_in_batches_with_error", Config{}),
*GetUser("find_in_batches_with_error", Config{}), *GetUser("find_in_batches_with_error", Config{}),

View File

@ -45,7 +45,7 @@ func TestScan(t *testing.T) {
t.Fatalf("Scan into struct should work, got %#v, should %#v", res, user3) t.Fatalf("Scan into struct should work, got %#v, should %#v", res, user3)
} }
var doubleAgeRes = &result{} doubleAgeRes := &result{}
if err := DB.Table("users").Select("age + age as age").Where("id = ?", user3.ID).Scan(&doubleAgeRes).Error; err != nil { if err := DB.Table("users").Select("age + age as age").Where("id = ?", user3.ID).Scan(&doubleAgeRes).Error; err != nil {
t.Errorf("Scan to pointer of pointer") t.Errorf("Scan to pointer of pointer")
} }

View File

@ -23,7 +23,7 @@ func NameIn(names []string) func(d *gorm.DB) *gorm.DB {
} }
func TestScopes(t *testing.T) { func TestScopes(t *testing.T) {
var users = []*User{ users := []*User{
GetUser("ScopeUser1", Config{}), GetUser("ScopeUser1", Config{}),
GetUser("ScopeUser2", Config{}), GetUser("ScopeUser2", Config{}),
GetUser("ScopeUser3", Config{}), GetUser("ScopeUser3", Config{}),

View File

@ -4,12 +4,11 @@ import (
"regexp" "regexp"
"strings" "strings"
"testing" "testing"
"time"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
. "gorm.io/gorm/utils/tests" . "gorm.io/gorm/utils/tests"
"time"
) )
func TestRow(t *testing.T) { func TestRow(t *testing.T) {
@ -389,12 +388,12 @@ func assertEqualSQL(t *testing.T, expected string, actually string) {
actually = replaceQuoteInSQL(actually) actually = replaceQuoteInSQL(actually)
// ignore updated_at value, becase it's generated in Gorm inernal, can't to mock value on update. // ignore updated_at value, becase it's generated in Gorm inernal, can't to mock value on update.
var updatedAtRe = regexp.MustCompile(`(?i)"updated_at"=".+?"`) updatedAtRe := regexp.MustCompile(`(?i)"updated_at"=".+?"`)
actually = updatedAtRe.ReplaceAllString(actually, `"updated_at"=?`) actually = updatedAtRe.ReplaceAllString(actually, `"updated_at"=?`)
expected = updatedAtRe.ReplaceAllString(expected, `"updated_at"=?`) expected = updatedAtRe.ReplaceAllString(expected, `"updated_at"=?`)
// ignore RETURNING "id" (only in PostgreSQL) // ignore RETURNING "id" (only in PostgreSQL)
var returningRe = regexp.MustCompile(`(?i)RETURNING "id"`) returningRe := regexp.MustCompile(`(?i)RETURNING "id"`)
actually = returningRe.ReplaceAllString(actually, ``) actually = returningRe.ReplaceAllString(actually, ``)
expected = returningRe.ReplaceAllString(expected, ``) expected = returningRe.ReplaceAllString(expected, ``)
@ -408,16 +407,16 @@ func assertEqualSQL(t *testing.T, expected string, actually string) {
func replaceQuoteInSQL(sql string) string { func replaceQuoteInSQL(sql string) string {
// convert single quote into double quote // convert single quote into double quote
sql = strings.Replace(sql, `'`, `"`, -1) sql = strings.ReplaceAll(sql, `'`, `"`)
// convert dialect speical quote into double quote // convert dialect speical quote into double quote
switch DB.Dialector.Name() { switch DB.Dialector.Name() {
case "postgres": case "postgres":
sql = strings.Replace(sql, `"`, `"`, -1) sql = strings.ReplaceAll(sql, `"`, `"`)
case "mysql", "sqlite": case "mysql", "sqlite":
sql = strings.Replace(sql, "`", `"`, -1) sql = strings.ReplaceAll(sql, "`", `"`)
case "sqlserver": case "sqlserver":
sql = strings.Replace(sql, `'`, `"`, -1) sql = strings.ReplaceAll(sql, `'`, `"`)
} }
return sql return sql

View File

@ -22,19 +22,19 @@ for dialect in "${dialects[@]}" ; do
if [ "$GORM_VERBOSE" = "" ] if [ "$GORM_VERBOSE" = "" ]
then then
GORM_DIALECT=${dialect} go test -race -count=1 ./... GORM_DIALECT=${dialect} go test -race -count=1 -coverprofile=coverage.out ./...
if [ -d tests ] if [ -d tests ]
then then
cd tests cd tests
GORM_DIALECT=${dialect} go test -race -count=1 ./... GORM_DIALECT=${dialect} go test -race -count=1 -coverprofile=../coverage.out ./...
cd .. cd ..
fi fi
else else
GORM_DIALECT=${dialect} go test -race -count=1 -v ./... GORM_DIALECT=${dialect} go test -race -count=1 -v -coverprofile=coverage.out ./...
if [ -d tests ] if [ -d tests ]
then then
cd tests cd tests
GORM_DIALECT=${dialect} go test -race -count=1 -v ./... GORM_DIALECT=${dialect} go test -race -count=1 -v -coverprofile=../coverage.out ./...
cd .. cd ..
fi fi
fi fi

View File

@ -11,6 +11,7 @@ import (
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/driver/sqlite" "gorm.io/driver/sqlite"
"gorm.io/driver/sqlserver" "gorm.io/driver/sqlserver"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
. "gorm.io/gorm/utils/tests" . "gorm.io/gorm/utils/tests"

View File

@ -8,7 +8,7 @@ import (
) )
func TestUpdateBelongsTo(t *testing.T) { func TestUpdateBelongsTo(t *testing.T) {
var user = *GetUser("update-belongs-to", Config{}) user := *GetUser("update-belongs-to", Config{})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)

View File

@ -8,7 +8,7 @@ import (
) )
func TestUpdateHasManyAssociations(t *testing.T) { func TestUpdateHasManyAssociations(t *testing.T) {
var user = *GetUser("update-has-many", Config{}) user := *GetUser("update-has-many", Config{})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -44,7 +44,7 @@ func TestUpdateHasManyAssociations(t *testing.T) {
CheckUser(t, user4, user) CheckUser(t, user4, user)
t.Run("Polymorphic", func(t *testing.T) { t.Run("Polymorphic", func(t *testing.T) {
var user = *GetUser("update-has-many", Config{}) user := *GetUser("update-has-many", Config{})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)

View File

@ -10,7 +10,7 @@ import (
) )
func TestUpdateHasOne(t *testing.T) { func TestUpdateHasOne(t *testing.T) {
var user = *GetUser("update-has-one", Config{}) user := *GetUser("update-has-one", Config{})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)
@ -35,7 +35,7 @@ func TestUpdateHasOne(t *testing.T) {
DB.Preload("Account").Find(&user3, "id = ?", user.ID) DB.Preload("Account").Find(&user3, "id = ?", user.ID)
CheckUser(t, user2, user3) CheckUser(t, user2, user3)
var lastUpdatedAt = user2.Account.UpdatedAt lastUpdatedAt := user2.Account.UpdatedAt
time.Sleep(time.Second) time.Sleep(time.Second)
if err := DB.Session(&gorm.Session{FullSaveAssociations: true}).Save(&user).Error; err != nil { if err := DB.Session(&gorm.Session{FullSaveAssociations: true}).Save(&user).Error; err != nil {
@ -53,7 +53,7 @@ func TestUpdateHasOne(t *testing.T) {
} }
t.Run("Polymorphic", func(t *testing.T) { t.Run("Polymorphic", func(t *testing.T) {
var pet = Pet{Name: "create"} pet := Pet{Name: "create"}
if err := DB.Create(&pet).Error; err != nil { if err := DB.Create(&pet).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)

View File

@ -8,7 +8,7 @@ import (
) )
func TestUpdateMany2ManyAssociations(t *testing.T) { func TestUpdateMany2ManyAssociations(t *testing.T) {
var user = *GetUser("update-many2many", Config{}) user := *GetUser("update-many2many", Config{})
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Fatalf("errors happened when create: %v", err) t.Fatalf("errors happened when create: %v", err)

View File

@ -125,7 +125,7 @@ func TestUpdate(t *testing.T) {
} }
func TestUpdates(t *testing.T) { func TestUpdates(t *testing.T) {
var users = []*User{ users := []*User{
GetUser("updates_01", Config{}), GetUser("updates_01", Config{}),
GetUser("updates_02", Config{}), GetUser("updates_02", Config{}),
} }
@ -178,7 +178,7 @@ func TestUpdates(t *testing.T) {
} }
func TestUpdateColumn(t *testing.T) { func TestUpdateColumn(t *testing.T) {
var users = []*User{ users := []*User{
GetUser("update_column_01", Config{}), GetUser("update_column_01", Config{}),
GetUser("update_column_02", Config{}), GetUser("update_column_02", Config{}),
} }
@ -622,7 +622,7 @@ func TestSave(t *testing.T) {
time.Sleep(time.Second) time.Sleep(time.Second)
user1UpdatedAt := result.UpdatedAt user1UpdatedAt := result.UpdatedAt
user2UpdatedAt := user2.UpdatedAt user2UpdatedAt := user2.UpdatedAt
var users = []*User{&result, &user2} users := []*User{&result, &user2}
DB.Save(&users) DB.Save(&users)
if user1UpdatedAt.Format(time.RFC1123Z) == result.UpdatedAt.Format(time.RFC1123Z) { if user1UpdatedAt.Format(time.RFC1123Z) == result.UpdatedAt.Format(time.RFC1123Z) {

View File

@ -67,7 +67,7 @@ func TestUpsert(t *testing.T) {
} }
} }
var user = *GetUser("upsert_on_conflict", Config{}) user := *GetUser("upsert_on_conflict", Config{})
user.Age = 20 user.Age = 20
if err := DB.Create(&user).Error; err != nil { if err := DB.Create(&user).Error; err != nil {
t.Errorf("failed to create user, got error %v", err) t.Errorf("failed to create user, got error %v", err)
@ -320,11 +320,9 @@ func TestUpdateWithMissWhere(t *testing.T) {
if err := tx.Error; err != nil { if err := tx.Error; err != nil {
t.Fatalf("failed to update user,missing where condtion,err=%+v", err) t.Fatalf("failed to update user,missing where condtion,err=%+v", err)
} }
if !regexp.MustCompile("WHERE .id. = [^ ]+$").MatchString(tx.Statement.SQL.String()) { if !regexp.MustCompile("WHERE .id. = [^ ]+$").MatchString(tx.Statement.SQL.String()) {
t.Fatalf("invalid updating SQL, got %v", tx.Statement.SQL.String()) t.Fatalf("invalid updating SQL, got %v", tx.Statement.SQL.String())
} }
} }

View File

@ -7,8 +7,7 @@ import (
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
) )
type DummyDialector struct { type DummyDialector struct{}
}
func (DummyDialector) Name() string { func (DummyDialector) Name() string {
return "dummy" return "dummy"