mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22:11 +08:00
## Summary
- Add 4 new test files for pgsql driver to align with MySQL driver test
coverage (86 test functions, ~3100 lines)
- `pgsql_z_unit_transaction_test.go`: 40 tests — TX CRUD, nested
transactions, propagation behaviors
(Required/RequiresNew/Nested/NotSupported/Mandatory/Never/Supports),
isolation levels (ReadCommitted/RepeatableRead/Serializable), savepoints
- `pgsql_z_unit_model_where_test.go`: 35 tests — Where variants
(string/slice/map/struct/gmap), comparisons (LT/LTE/GT/GTE), IN/NotIn,
Between, Like, Null, EXISTS/NOT EXISTS subqueries, WherePrefix with JOIN
- `pgsql_z_unit_feature_hook_test.go`: 6 tests —
Select/Insert/Update/Delete hooks, Count with hook, hook chaining and
error handling
- `pgsql_z_unit_feature_ctx_test.go`: 5 tests — context propagation,
trace logging (SpanId/TraceId), transaction context, timeout
cancellation
- Migrate `Test_Model_Where` from `pgsql_z_unit_model_test.go` to
dedicated where test file with expanded coverage (2 → 30+ sub-tests)
**PostgreSQL adaptations from MySQL:**
- `?` → `$N` placeholders for raw SQL
- `REPLACE INTO` → `OnConflict("id").Save()` for upsert
- `AUTO_INCREMENT` → `bigserial`
- `user` alias → `"user"` (reserved word in PgSQL)
- Skip `READ UNCOMMITTED` dirty read test (PgSQL treats as READ
COMMITTED)
## Test plan
- [ ] Run `go test -v -run "Test_TX_" -count=1` in
`contrib/drivers/pgsql`
- [ ] Run `go test -v -run "Test_Model_Where" -count=1` in
`contrib/drivers/pgsql`
- [ ] Run `go test -v -run "Test_Model_Hook" -count=1` in
`contrib/drivers/pgsql`
- [ ] Run `go test -v -run "Test_Ctx" -count=1` in
`contrib/drivers/pgsql`
- [ ] Verify `go vet ./...` passes (only unreachable code warnings
matching MySQL driver pattern)
ref #4689
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
package pgsql_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gogf/gf/v2/database/gdb"
|
|
"github.com/gogf/gf/v2/os/glog"
|
|
"github.com/gogf/gf/v2/test/gtest"
|
|
)
|
|
|
|
func Test_Ctx(t *testing.T) {
|
|
gtest.C(t, func(t *gtest.T) {
|
|
db, err := gdb.Instance()
|
|
t.AssertNil(err)
|
|
|
|
err1 := db.PingMaster()
|
|
err2 := db.PingSlave()
|
|
t.Assert(err1, nil)
|
|
t.Assert(err2, nil)
|
|
|
|
newDb := db.Ctx(context.Background())
|
|
t.AssertNE(newDb, nil)
|
|
})
|
|
}
|
|
|
|
func Test_Ctx_Query(t *testing.T) {
|
|
db.GetLogger().(*glog.Logger).SetCtxKeys("SpanId", "TraceId")
|
|
gtest.C(t, func(t *gtest.T) {
|
|
db.SetDebug(true)
|
|
defer db.SetDebug(false)
|
|
ctx := context.WithValue(context.Background(), "TraceId", "12345678")
|
|
ctx = context.WithValue(ctx, "SpanId", "0.1")
|
|
db.Query(ctx, "select 1")
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
db.SetDebug(true)
|
|
defer db.SetDebug(false)
|
|
db.Query(ctx, "select 2")
|
|
})
|
|
}
|
|
|
|
func Test_Ctx_Model(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
db.GetLogger().(*glog.Logger).SetCtxKeys("SpanId", "TraceId")
|
|
gtest.C(t, func(t *gtest.T) {
|
|
db.SetDebug(true)
|
|
defer db.SetDebug(false)
|
|
ctx := context.WithValue(context.Background(), "TraceId", "12345678")
|
|
ctx = context.WithValue(ctx, "SpanId", "0.1")
|
|
db.Model(table).Ctx(ctx).All()
|
|
})
|
|
gtest.C(t, func(t *gtest.T) {
|
|
db.SetDebug(true)
|
|
defer db.SetDebug(false)
|
|
db.Model(table).All()
|
|
})
|
|
}
|
|
|
|
func Test_Ctx_Transaction(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
|
|
db.GetLogger().(*glog.Logger).SetCtxKeys("SpanId", "TraceId")
|
|
gtest.C(t, func(t *gtest.T) {
|
|
db.SetDebug(true)
|
|
defer db.SetDebug(false)
|
|
ctx := context.WithValue(context.Background(), "TraceId", "tx_trace_123")
|
|
ctx = context.WithValue(ctx, "SpanId", "0.2")
|
|
|
|
err := db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
|
_, err := tx.Model(table).Ctx(ctx).Where("id", 1).One()
|
|
return err
|
|
})
|
|
t.AssertNil(err)
|
|
})
|
|
}
|
|
|
|
func Test_Ctx_Timeout(t *testing.T) {
|
|
table := createInitTable()
|
|
defer dropTable(table)
|
|
|
|
gtest.C(t, func(t *gtest.T) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*10)
|
|
defer cancel()
|
|
|
|
// Wait for the context to expire
|
|
time.Sleep(time.Millisecond * 50)
|
|
|
|
// Query with expired context should return error
|
|
_, err := db.Model(table).Ctx(ctx).All()
|
|
t.AssertNE(err, nil)
|
|
})
|
|
}
|