Merge pull request #1 from incident-io/henrycourse/upgrade-gorm-ww24

Gorm upgrade to 1.25 and tweaks
This commit is contained in:
Henry Course 2024-10-10 10:40:29 +01:00 committed by GitHub
commit bf5cd45b03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 112 additions and 27 deletions

23
.github/workflows/release-on-tag.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: Create Release on Tag
on:
push:
tags:
- '*'
jobs:
create_release:
runs-on: ubuntu-latest
steps:
- name: Create Release
uses: actions/create-release@v1
with:
tag_name: ${{ github.ref_name }}
release_name: ${{ github.ref_name }}
body: |
Release ${{ github.ref_name }} of GORM.
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -176,17 +176,15 @@ jobs:
services: services:
mssql: mssql:
image: mcmoe/mssqldocker:latest image: mcr.microsoft.com/mssql/server:2022-latest
env: env:
TZ: Asia/Shanghai
ACCEPT_EULA: Y ACCEPT_EULA: Y
SA_PASSWORD: LoremIpsum86 MSSQL_SA_PASSWORD: LoremIpsum86
MSSQL_DB: gorm
MSSQL_USER: gorm
MSSQL_PASSWORD: LoremIpsum86
ports: ports:
- 9930:1433 - 9930:1433
options: >- options: >-
--health-cmd="/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P LoremIpsum86 -l 30 -Q \"SELECT 1\" || exit 1" --health-cmd="/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P ${MSSQL_SA_PASSWORD} -N -C -l 30 -Q \"SELECT 1\" || exit 1"
--health-start-period 10s --health-start-period 10s
--health-interval 10s --health-interval 10s
--health-timeout 5s --health-timeout 5s
@ -208,7 +206,7 @@ jobs:
key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('tests/go.mod') }} key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('tests/go.mod') }}
- name: Tests - name: Tests
run: GITHUB_ACTION=true GORM_DIALECT=sqlserver GORM_DSN="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" ./tests/tests_all.sh run: GITHUB_ACTION=true GORM_DIALECT=sqlserver GORM_DSN="sqlserver://sa:LoremIpsum86@localhost:9930?database=master" ./tests/tests_all.sh
tidb: tidb:
strategy: strategy:

View File

@ -4,6 +4,7 @@ import (
"database/sql" "database/sql"
"errors" "errors"
"fmt" "fmt"
"hash/maphash"
"reflect" "reflect"
"strings" "strings"
@ -623,14 +624,15 @@ func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err er
if committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil { if committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil {
// nested transaction // nested transaction
if !db.DisableNestedTransaction { if !db.DisableNestedTransaction {
err = db.SavePoint(fmt.Sprintf("sp%p", fc)).Error spID := new(maphash.Hash).Sum64()
err = db.SavePoint(fmt.Sprintf("sp%d", spID)).Error
if err != nil { if err != nil {
return return
} }
defer func() { defer func() {
// Make sure to rollback when panic, Block error or Commit error // Make sure to rollback when panic, Block error or Commit error
if panicked || err != nil { if panicked || err != nil {
db.RollbackTo(fmt.Sprintf("sp%p", fc)) db.RollbackTo(fmt.Sprintf("sp%d", spID))
} }
}() }()
} }

View File

@ -12,6 +12,7 @@ import (
"time" "time"
"github.com/jinzhu/now" "github.com/jinzhu/now"
"gorm.io/gorm/clause" "gorm.io/gorm/clause"
"gorm.io/gorm/utils" "gorm.io/gorm/utils"
) )
@ -922,7 +923,7 @@ func (field *Field) setupValuerAndSetter() {
if !reflectV.IsValid() { if !reflectV.IsValid() {
field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem()) field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem())
} else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() { } else if reflectV.Kind() == reflect.Ptr && reflectV.IsNil() {
return field.ReflectValueOf(ctx, value).Set(reflect.New(field.FieldType).Elem())
} else if reflectV.Type().AssignableTo(field.FieldType) { } else if reflectV.Type().AssignableTo(field.FieldType) {
field.ReflectValueOf(ctx, value).Set(reflectV) field.ReflectValueOf(ctx, value).Set(reflectV)
} else if reflectV.Kind() == reflect.Ptr { } else if reflectV.Kind() == reflect.Ptr {

View File

@ -1,5 +1,3 @@
version: '3'
services: services:
mysql: mysql:
image: 'mysql/mysql-server:latest' image: 'mysql/mysql-server:latest'
@ -20,16 +18,13 @@ services:
- POSTGRES_USER=gorm - POSTGRES_USER=gorm
- POSTGRES_PASSWORD=gorm - POSTGRES_PASSWORD=gorm
mssql: mssql:
image: '${MSSQL_IMAGE:-mcmoe/mssqldocker}:latest' image: '${MSSQL_IMAGE}:2022-latest'
ports: ports:
- "127.0.0.1:9930:1433" - "127.0.0.1:9930:1433"
environment: environment:
- TZ=Asia/Shanghai - TZ=Asia/Shanghai
- ACCEPT_EULA=Y - ACCEPT_EULA=Y
- SA_PASSWORD=LoremIpsum86 - MSSQL_SA_PASSWORD=LoremIpsum86
- MSSQL_DB=gorm
- MSSQL_USER=gorm
- MSSQL_PASSWORD=LoremIpsum86
tidb: tidb:
image: 'pingcap/tidb:v6.5.0' image: 'pingcap/tidb:v6.5.0'
ports: ports:

View File

@ -11,7 +11,7 @@ require (
gorm.io/driver/postgres v1.5.9 gorm.io/driver/postgres v1.5.9
gorm.io/driver/sqlite v1.5.6 gorm.io/driver/sqlite v1.5.6
gorm.io/driver/sqlserver v1.5.3 gorm.io/driver/sqlserver v1.5.3
gorm.io/gorm v1.25.10 gorm.io/gorm v1.25.12
) )
require ( require (
@ -22,20 +22,18 @@ require (
github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.6.0 // indirect github.com/jackc/pgx/v5 v5.7.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/kr/text v0.2.0 // indirect github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/mattn/go-sqlite3 v1.14.23 // indirect
github.com/microsoft/go-mssqldb v1.7.2 // indirect github.com/microsoft/go-mssqldb v1.7.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect
golang.org/x/crypto v0.24.0 // indirect golang.org/x/crypto v0.27.0 // indirect
golang.org/x/text v0.16.0 // indirect golang.org/x/text v0.18.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )
replace gorm.io/gorm => ../ replace gorm.io/gorm => ../
replace github.com/jackc/pgx/v5 => github.com/jackc/pgx/v5 v5.4.3
replace github.com/microsoft/go-mssqldb => github.com/microsoft/go-mssqldb v1.7.0 replace github.com/microsoft/go-mssqldb => github.com/microsoft/go-mssqldb v1.7.0

View File

@ -21,13 +21,13 @@ if [[ -z $GITHUB_ACTION ]]; then
then then
cd tests cd tests
if [[ $(uname -a) == *" arm64" ]]; then if [[ $(uname -a) == *" arm64" ]]; then
MSSQL_IMAGE=mcr.microsoft.com/azure-sql-edge docker-compose start || true MSSQL_IMAGE=mcr.microsoft.com/azure-sql-edge docker compose up -d || true
go install github.com/microsoft/go-sqlcmd/cmd/sqlcmd@latest || true go install github.com/microsoft/go-sqlcmd/cmd/sqlcmd@latest || true
SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF DB_ID('gorm') IS NULL CREATE DATABASE gorm" > /dev/null || true SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF DB_ID('gorm') IS NULL CREATE DATABASE gorm" > /dev/null || true
SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF SUSER_ID (N'gorm') IS NULL CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86';" > /dev/null || true SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF SUSER_ID (N'gorm') IS NULL CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86';" > /dev/null || true
SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF USER_ID (N'gorm') IS NULL CREATE USER gorm FROM LOGIN gorm; ALTER SERVER ROLE sysadmin ADD MEMBER [gorm];" > /dev/null || true SQLCMDPASSWORD=LoremIpsum86 sqlcmd -U sa -S localhost:9930 -Q "IF USER_ID (N'gorm') IS NULL CREATE USER gorm FROM LOGIN gorm; ALTER SERVER ROLE sysadmin ADD MEMBER [gorm];" > /dev/null || true
else else
docker-compose start MSSQL_IMAGE=mcr.microsoft.com/mssql/server docker compose up -d
fi fi
cd .. cd ..
fi fi

View File

@ -20,7 +20,7 @@ var DB *gorm.DB
var ( var (
mysqlDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local" mysqlDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local"
postgresDSN = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai" postgresDSN = "user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai"
sqlserverDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" sqlserverDSN = "sqlserver://sa:LoremIpsum86@localhost:9930?database=master"
tidbDSN = "root:@tcp(localhost:9940)/test?charset=utf8&parseTime=True&loc=Local" tidbDSN = "root:@tcp(localhost:9940)/test?charset=utf8&parseTime=True&loc=Local"
) )

View File

@ -297,6 +297,74 @@ func TestNestedTransactionWithBlock(t *testing.T) {
} }
} }
func TestDeeplyNestedTransactionWithBlockAndWrappedCallback(t *testing.T) {
transaction := func(ctx context.Context, db *gorm.DB, callback func(ctx context.Context, db *gorm.DB) error) error {
return db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
return callback(ctx, tx)
})
}
var (
user = *GetUser("transaction-nested", Config{})
user1 = *GetUser("transaction-nested-1", Config{})
user2 = *GetUser("transaction-nested-2", Config{})
)
if err := transaction(context.Background(), DB, func(ctx context.Context, tx *gorm.DB) error {
tx.Create(&user)
if err := tx.First(&User{}, "name = ?", user.Name).Error; err != nil {
t.Fatalf("Should find saved record")
}
if err := transaction(ctx, tx, func(ctx context.Context, tx1 *gorm.DB) error {
tx1.Create(&user1)
if err := tx1.First(&User{}, "name = ?", user1.Name).Error; err != nil {
t.Fatalf("Should find saved record")
}
if err := transaction(ctx, tx1, func(ctx context.Context, tx2 *gorm.DB) error {
tx2.Create(&user2)
if err := tx2.First(&User{}, "name = ?", user2.Name).Error; err != nil {
t.Fatalf("Should find saved record")
}
return errors.New("inner rollback")
}); err == nil {
t.Fatalf("nested transaction has no error")
}
return errors.New("rollback")
}); err == nil {
t.Fatalf("nested transaction should returns error")
}
if err := tx.First(&User{}, "name = ?", user1.Name).Error; err == nil {
t.Fatalf("Should not find rollbacked record")
}
if err := tx.First(&User{}, "name = ?", user2.Name).Error; err != nil {
t.Fatalf("Should find saved record")
}
return nil
}); err != nil {
t.Fatalf("no error should return, but got %v", err)
}
if err := DB.First(&User{}, "name = ?", user.Name).Error; err != nil {
t.Fatalf("Should find saved record")
}
if err := DB.First(&User{}, "name = ?", user1.Name).Error; err == nil {
t.Fatalf("Should not find rollbacked parent record")
}
if err := DB.First(&User{}, "name = ?", user2.Name).Error; err != nil {
t.Fatalf("Should not find rollbacked nested record")
}
}
func TestDisabledNestedTransaction(t *testing.T) { func TestDisabledNestedTransaction(t *testing.T) {
var ( var (
user = *GetUser("transaction-nested", Config{}) user = *GetUser("transaction-nested", Config{})