From e265bee039d0c7f79cf6a5848517ceb578b996c7 Mon Sep 17 00:00:00 2001 From: benjababe Date: Mon, 21 Jul 2025 10:06:18 +0800 Subject: [PATCH 1/4] test: include sql server schema test --- db.go | 11 ++++++++++- go.mod | 27 ++++++++++++++++----------- main_test.go | 29 ++++++++++++++++++++++++----- models.go | 11 +++++++++++ 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/db.go b/db.go index ccab03ed..12ba8472 100644 --- a/db.go +++ b/db.go @@ -67,6 +67,14 @@ func OpenTestConnection() (db *gorm.DB, err error) { dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" } db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{}) + db.Exec(` + IF NOT EXISTS( + SELECT * FROM sys.schemas WHERE name = 'test_schema' + ) + BEGIN + EXEC('CREATE SCHEMA test_schema') + END + `) default: log.Println("testing sqlite3...") db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), &gorm.Config{}) @@ -83,7 +91,8 @@ func OpenTestConnection() (db *gorm.DB, err error) { func RunMigrations() { var err error - allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}} + + allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}, &TestStruct{}} rand.Seed(time.Now().UnixNano()) rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] }) diff --git a/go.mod b/go.mod index d1ba4316..f301bd61 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,15 @@ go 1.23.0 toolchain go1.24.3 +// For SQL Server +godebug ( + x509negativeserial=1 +) + require ( - gorm.io/driver/mysql v1.5.7 - gorm.io/driver/postgres v1.5.11 - gorm.io/driver/sqlite v1.5.7 + gorm.io/driver/mysql v1.6.0 + gorm.io/driver/postgres v1.6.0 + gorm.io/driver/sqlite v1.6.0 gorm.io/driver/sqlserver v1.6.0 gorm.io/gen v0.3.27 gorm.io/gorm v1.30.0 @@ -15,7 +20,7 @@ require ( require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/go-sql-driver/mysql v1.9.2 // indirect + github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/google/uuid v1.6.0 // indirect @@ -26,13 +31,13 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/mattn/go-sqlite3 v1.14.28 // indirect - github.com/microsoft/go-mssqldb v1.8.1 // indirect - golang.org/x/crypto v0.38.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/sync v0.14.0 // indirect - golang.org/x/text v0.25.0 // indirect - golang.org/x/tools v0.33.0 // indirect - gorm.io/datatypes v1.2.5 // indirect + github.com/microsoft/go-mssqldb v1.9.2 // indirect + golang.org/x/crypto v0.40.0 // indirect + golang.org/x/mod v0.26.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/text v0.27.0 // indirect + golang.org/x/tools v0.35.0 // indirect + gorm.io/datatypes v1.2.6 // indirect gorm.io/hints v1.1.2 // indirect gorm.io/plugin/dbresolver v1.6.0 // indirect ) diff --git a/main_test.go b/main_test.go index 60a388f7..7491c277 100644 --- a/main_test.go +++ b/main_test.go @@ -2,6 +2,8 @@ package main import ( "testing" + + "gorm.io/gorm" ) // GORM_REPO: https://github.com/go-gorm/gorm.git @@ -9,12 +11,29 @@ import ( // TEST_DRIVERS: sqlite, mysql, postgres, sqlserver func TestGORM(t *testing.T) { - user := User{Name: "jinzhu"} + var result *gorm.DB + var ts TestStruct + + // Try inserting into DB without manually specifying identity column value + workTestStruct := TestStruct{Value: "hello"} + result = DB.Create(&workTestStruct) + if err := result.Error; err != nil { + t.Errorf("Failed to create workTestStruct: %+v", err) + } - DB.Create(&user) + if err := DB.First(&ts, workTestStruct.ID).Error; err != nil { + t.Errorf("Failed to read workTestStruct, got error: %v", err) + } + + // Try again but specifying the identity column value. + // The insert should fail here due to the schema not being included in the `SET IDENTITY_INSERT` statement + failTestStruct := TestStruct{ID: 100, Value: "there"} + result = DB.Create(&failTestStruct) + if err := result.Error; err != nil { + t.Errorf("Failed to create failTestStruct: %+v", err) + } - var result User - if err := DB.First(&result, user.ID).Error; err != nil { - t.Errorf("Failed, got error: %v", err) + if err := DB.First(&ts, failTestStruct.ID).Error; err != nil { + t.Errorf("Failed to read failTestStruct, got error: %v", err) } } diff --git a/models.go b/models.go index 692a6842..a0632c03 100644 --- a/models.go +++ b/models.go @@ -58,3 +58,14 @@ type Language struct { Code string `gorm:"primarykey"` Name string } + +type TestStruct struct { + ID uint `gorm:"primarykey,autoIncrement"` + CreatedAt time.Time + UpdatedAt time.Time + Value string +} + +func (TestStruct) TableName() string { + return "test_schema.test_structs" +} From 0f929b0876bdefa6fc166aa07e2c672225be4a95 Mon Sep 17 00:00:00 2001 From: benjababe Date: Mon, 21 Jul 2025 10:34:05 +0800 Subject: [PATCH 2/4] test: use namingstrategy instead --- db.go | 46 +++++++++++++++++++++++++--------------------- models.go | 4 ---- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/db.go b/db.go index 12ba8472..da141418 100644 --- a/db.go +++ b/db.go @@ -13,6 +13,7 @@ import ( "gorm.io/driver/sqlserver" "gorm.io/gorm" "gorm.io/gorm/logger" + "gorm.io/gorm/schema" ) var DB *gorm.DB @@ -22,23 +23,24 @@ func init() { if DB, err = OpenTestConnection(); err != nil { log.Printf("failed to connect database, got error %v\n", err) os.Exit(1) - } else { - sqlDB, err := DB.DB() - if err == nil { - err = sqlDB.Ping() - } + } - if err != nil { - log.Printf("failed to connect database, got error %v\n", err) - } + sqlDB, err := DB.DB() + if err == nil { + err = sqlDB.Ping() + } - RunMigrations() - if DB.Dialector.Name() == "sqlite" { - DB.Exec("PRAGMA foreign_keys = ON") - } + if err != nil { + log.Printf("failed to connect database, got error %v\n", err) + } - DB.Logger = DB.Logger.LogMode(logger.Info) + RunMigrations() + if DB.Dialector.Name() == "sqlite" { + DB.Exec("PRAGMA foreign_keys = ON") } + + DB.Logger = DB.Logger.LogMode(logger.Info) + } func OpenTestConnection() (db *gorm.DB, err error) { @@ -66,13 +68,15 @@ func OpenTestConnection() (db *gorm.DB, err error) { if dbDSN == "" { dbDSN = "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" } - db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{}) + db, err = gorm.Open(sqlserver.Open(dbDSN), &gorm.Config{ + NamingStrategy: schema.NamingStrategy{TablePrefix: "testing_schema."}, + }) db.Exec(` IF NOT EXISTS( - SELECT * FROM sys.schemas WHERE name = 'test_schema' + SELECT * FROM sys.schemas WHERE name = 'testing_schema' ) BEGIN - EXEC('CREATE SCHEMA test_schema') + EXEC('CREATE SCHEMA testing_schema') END `) default: @@ -92,16 +96,16 @@ func OpenTestConnection() (db *gorm.DB, err error) { func RunMigrations() { var err error - allModels := []interface{}{&User{}, &Account{}, &Pet{}, &Company{}, &Toy{}, &Language{}, &TestStruct{}} + allModels := []interface{}{&Company{}, &TestStruct{}} rand.Seed(time.Now().UnixNano()) rand.Shuffle(len(allModels), func(i, j int) { allModels[i], allModels[j] = allModels[j], allModels[i] }) DB.Migrator().DropTable("user_friends", "user_speaks") - if err = DB.Migrator().DropTable(allModels...); err != nil { - log.Printf("Failed to drop table, got error %v\n", err) - os.Exit(1) - } + // if err = DB.Migrator().DropTable(allModels...); err != nil { + // log.Printf("Failed to drop table, got error %v\n", err) + // os.Exit(1) + // } if err = DB.AutoMigrate(allModels...); err != nil { log.Printf("Failed to auto migrate, but got error %v\n", err) diff --git a/models.go b/models.go index a0632c03..b417a538 100644 --- a/models.go +++ b/models.go @@ -65,7 +65,3 @@ type TestStruct struct { UpdatedAt time.Time Value string } - -func (TestStruct) TableName() string { - return "test_schema.test_structs" -} From 70b8172ea7c6ba28731771dbae6da9903e4a150c Mon Sep 17 00:00:00 2001 From: benjababe Date: Mon, 21 Jul 2025 10:45:30 +0800 Subject: [PATCH 3/4] test: fix test code --- db.go | 8 ++++---- main_test.go | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/db.go b/db.go index da141418..3f235139 100644 --- a/db.go +++ b/db.go @@ -102,10 +102,10 @@ func RunMigrations() { DB.Migrator().DropTable("user_friends", "user_speaks") - // if err = DB.Migrator().DropTable(allModels...); err != nil { - // log.Printf("Failed to drop table, got error %v\n", err) - // os.Exit(1) - // } + if err = DB.Migrator().DropTable(allModels...); err != nil { + log.Printf("Failed to drop table, got error %v\n", err) + os.Exit(1) + } if err = DB.AutoMigrate(allModels...); err != nil { log.Printf("Failed to auto migrate, but got error %v\n", err) diff --git a/main_test.go b/main_test.go index 7491c277..1366ff3c 100644 --- a/main_test.go +++ b/main_test.go @@ -12,7 +12,6 @@ import ( func TestGORM(t *testing.T) { var result *gorm.DB - var ts TestStruct // Try inserting into DB without manually specifying identity column value workTestStruct := TestStruct{Value: "hello"} @@ -21,7 +20,8 @@ func TestGORM(t *testing.T) { t.Errorf("Failed to create workTestStruct: %+v", err) } - if err := DB.First(&ts, workTestStruct.ID).Error; err != nil { + var ts1 TestStruct + if err := DB.First(&ts1, workTestStruct.ID).Error; err != nil { t.Errorf("Failed to read workTestStruct, got error: %v", err) } @@ -33,7 +33,8 @@ func TestGORM(t *testing.T) { t.Errorf("Failed to create failTestStruct: %+v", err) } - if err := DB.First(&ts, failTestStruct.ID).Error; err != nil { + var ts2 TestStruct + if err := DB.First(&ts2, failTestStruct.ID).Error; err != nil { t.Errorf("Failed to read failTestStruct, got error: %v", err) } } From 4655d0c2e834998b4314ec595174d9c8e6cb7a91 Mon Sep 17 00:00:00 2001 From: benjababe Date: Mon, 21 Jul 2025 10:49:03 +0800 Subject: [PATCH 4/4] ci: update workflow cache ver --- .github/workflows/tests.yml | 126 ++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a1a33bf9..7b141375 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,44 +2,44 @@ name: tests on: push: - branches: [ master ] + branches: [master] pull_request: branches-ignore: - - 'gh-pages' + - "gh-pages" jobs: # Label of the container job sqlite: strategy: matrix: - go: ['1.24'] + go: ["1.24"] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} steps: - - name: Set up Go 1.x - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go }} + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} - - name: Check out code into the Go module directory - uses: actions/checkout@v2 + - name: Check out code into the Go module directory + uses: actions/checkout@v2 - - name: go mod pakcage cache - uses: actions/cache@v4 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} + - name: go mod pakcage cache + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} - - name: Tests - run: GORM_DIALECT=sqlite ./test.sh + - name: Tests + run: GORM_DIALECT=sqlite ./test.sh mysql: needs: sqlite strategy: matrix: - dbversion: ['mysql:latest'] # 'mysql:5.7', 'mysql:5.6' - go: ['1.24'] + dbversion: ["mysql:latest"] # 'mysql:5.7', 'mysql:5.6' + go: ["1.24"] platform: [ubuntu-latest] runs-on: ${{ matrix.platform }} @@ -61,29 +61,29 @@ jobs: --health-retries 10 steps: - - name: Set up Go 1.x - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go }} + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} - - name: Check out code into the Go module directory - uses: actions/checkout@v2 + - name: Check out code into the Go module directory + uses: actions/checkout@v2 - - name: go mod pakcage cache - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} + - name: go mod pakcage cache + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} - - name: Tests - run: GORM_ENABLE_CACHE=true GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True" ./test.sh + - name: Tests + run: GORM_ENABLE_CACHE=true GORM_DIALECT=mysql GORM_DSN="gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True" ./test.sh postgres: needs: sqlite strategy: matrix: - dbversion: ['postgres:latest'] # 'postgres:11', 'postgres:10' - go: ['1.24'] + dbversion: ["postgres:latest"] # 'postgres:11', 'postgres:10' + go: ["1.24"] platform: [ubuntu-latest] # can not run in macOS and widnowsOS runs-on: ${{ matrix.platform }} @@ -105,28 +105,28 @@ jobs: --health-retries 5 steps: - - name: Set up Go 1.x - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go }} + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} - - name: Check out code into the Go module directory - uses: actions/checkout@v2 + - name: Check out code into the Go module directory + uses: actions/checkout@v2 - - name: go mod pakcage cache - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} + - name: go mod pakcage cache + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} - - name: Tests - run: GORM_ENABLE_CACHE=true GORM_DIALECT=postgres GORM_DSN="user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai" ./test.sh + - name: Tests + run: GORM_ENABLE_CACHE=true GORM_DIALECT=postgres GORM_DSN="user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai" ./test.sh sqlserver: needs: sqlite strategy: matrix: - go: ['1.24'] + go: ["1.24"] platform: [ubuntu-latest] # can not run test in macOS and windows runs-on: ${{ matrix.platform }} @@ -149,19 +149,19 @@ jobs: --health-retries 10 steps: - - name: Set up Go 1.x - uses: actions/setup-go@v2 - with: - go-version: ${{ matrix.go }} - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: go mod pakcage cache - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} - - - name: Tests - run: GORM_ENABLE_CACHE=true GORM_DIALECT=sqlserver GORM_DSN="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" ./test.sh + - name: Set up Go 1.x + uses: actions/setup-go@v2 + with: + go-version: ${{ matrix.go }} + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + + - name: go mod pakcage cache + uses: actions/cache@v4 + with: + path: ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ matrix.go }}-${{ hashFiles('go.mod') }} + + - name: Tests + run: GORM_ENABLE_CACHE=true GORM_DIALECT=sqlserver GORM_DSN="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm" ./test.sh