diff --git a/db.go b/db.go index ccab03ed..992579d9 100644 --- a/db.go +++ b/db.go @@ -1,12 +1,16 @@ package main import ( + "context" "log" "math/rand" "os" "path/filepath" "time" + "github.com/jackc/pgx/v5/pgxpool" + "github.com/jackc/pgx/v5/stdlib" + "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" @@ -42,6 +46,8 @@ func init() { } func OpenTestConnection() (db *gorm.DB, err error) { + config := &gorm.Config{PrepareStmt: true} + dbDSN := os.Getenv("GORM_DSN") switch os.Getenv("GORM_DIALECT") { case "mysql": @@ -49,13 +55,23 @@ func OpenTestConnection() (db *gorm.DB, err error) { if dbDSN == "" { dbDSN = "gorm:gorm@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local" } - db, err = gorm.Open(mysql.Open(dbDSN), &gorm.Config{}) + db, err = gorm.Open(mysql.Open(dbDSN), config) case "postgres": log.Println("testing postgres...") if dbDSN == "" { - dbDSN = "user=gorm password=gorm host=localhost dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai" + dbDSN = "user=gorm password=gorm host=localhost dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai pool_max_conns=2" + } + var poolConfig *pgxpool.Config + if poolConfig, err = pgxpool.ParseConfig(dbDSN); err != nil { + break + } + var pool *pgxpool.Pool + if pool, err = pgxpool.NewWithConfig(context.Background(), poolConfig); err != nil { + break } - db, err = gorm.Open(postgres.Open(dbDSN), &gorm.Config{}) + conn := stdlib.OpenDBFromPool(pool) + dialector := postgres.New(postgres.Config{Conn: conn}) + db, err = gorm.Open(dialector, config) case "sqlserver": // CREATE LOGIN gorm WITH PASSWORD = 'LoremIpsum86'; // CREATE DATABASE gorm; @@ -66,7 +82,7 @@ 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), config) default: log.Println("testing sqlite3...") db, err = gorm.Open(sqlite.Open(filepath.Join(os.TempDir(), "gorm.db")), &gorm.Config{}) diff --git a/go.mod b/go.mod index f194634f..2c9b68f1 100644 --- a/go.mod +++ b/go.mod @@ -1,41 +1,40 @@ module gorm.io/playground -go 1.22.0 +go 1.23.0 toolchain go1.23.3 require ( + github.com/jackc/pgx/v5 v5.7.5 gorm.io/driver/mysql v1.5.7 - gorm.io/driver/postgres v1.5.10 - gorm.io/driver/sqlite v1.5.6 + gorm.io/driver/postgres v1.5.11 + gorm.io/driver/sqlite v1.5.7 gorm.io/driver/sqlserver v1.5.4 - gorm.io/gen v0.3.26 - gorm.io/gorm v1.25.12 + gorm.io/gen v0.3.27 + gorm.io/gorm v1.26.1 ) require ( filippo.io/edwards25519 v1.1.0 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/go-sql-driver/mysql v1.9.2 // 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 github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.1 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-sqlite3 v1.14.24 // indirect - github.com/microsoft/go-mssqldb v1.7.2 // indirect - golang.org/x/crypto v0.29.0 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.27.0 // indirect - gorm.io/datatypes v1.2.4 // 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 gorm.io/hints v1.1.2 // indirect - gorm.io/plugin/dbresolver v1.5.3 // indirect + gorm.io/plugin/dbresolver v1.6.0 // indirect ) replace gorm.io/gorm => ./gorm diff --git a/main_test.go b/main_test.go index 60a388f7..8dac2352 100644 --- a/main_test.go +++ b/main_test.go @@ -1,20 +1,56 @@ package main import ( + "sync" "testing" + "time" + + "gorm.io/gorm" ) // GORM_REPO: https://github.com/go-gorm/gorm.git // GORM_BRANCH: master -// TEST_DRIVERS: sqlite, mysql, postgres, sqlserver +// TEST_DRIVERS: postgres func TestGORM(t *testing.T) { - user := User{Name: "jinzhu"} + db := DB + + transactionalClients := []string{"Alice", "Bob"} + var started, finished sync.WaitGroup + started.Add(len(transactionalClients)) + finished.Add(len(transactionalClients)) + + for _, clientName := range transactionalClients { + go func() { + db.Transaction(func(db *gorm.DB) error { + started.Done() + defer finished.Done() - DB.Create(&user) + t.Logf("%s has a connection and is thinking...", clientName) + doSomeWork() - var result User - if err := DB.First(&result, user.ID).Error; err != nil { - t.Errorf("Failed, got error: %v", err) + return addTwoNumbers(t, db, clientName) + }) + }() } + started.Wait() + + addTwoNumbers(t, db, "Camille") + finished.Wait() +} + +func addTwoNumbers(t *testing.T, db *gorm.DB, clientName string) error { + t.Logf("%s wants to add two numbers...", clientName) + var sum int32 + err := db.Raw("SELECT $1::int + $2::int", 2, 2).First(&sum).Error + if err != nil { + t.Errorf("%s failed: %s", clientName, err) + return err + } + t.Logf("%s thinks that 2 + 2 = %v", clientName, sum) + return nil +} + +func doSomeWork() { + time.Sleep(time.Second) }