Files
gf/contrib/drivers/pgsql/pgsql_z_unit_open_test.go
ivothgle d353bf0fbc feat(contrib/drivers/pgsql): more field types converting support (#3737)
This pull request significantly improves PostgreSQL array type handling
and conversion in the `pgsql` driver, providing more accurate type
mapping and conversion logic, especially for array types. It introduces
comprehensive documentation, refactors conversion logic to use the `pq`
package for array types, and adds extensive unit tests to ensure
correctness and error handling. Additionally, minor enhancements and
clarifications are made to upsert formatting and table field queries.

### PostgreSQL Array Type Handling and Conversion

* Refactored `CheckLocalTypeForField` and `ConvertValueForLocal` methods
in `contrib/drivers/pgsql/pgsql_convert.go` to accurately map PostgreSQL
array types (such as `_int2`, `_int4`, `_int8`, `_float4`, `_float8`,
`_bool`, `_varchar`, `_text`, `_char`, `_bpchar`, `_numeric`,
`_decimal`, `_money`, `_bytea`) to their corresponding Go types, using
the `pq` package for conversion. Added detailed documentation and
mapping tables for supported types.
[[1]](diffhunk://#diff-a3b1e68bfa29fbcfda7c703bbe875fa82e958f6c3ad942ef82193a9dd8ad67e2R46-R63)
[[2]](diffhunk://#diff-a3b1e68bfa29fbcfda7c703bbe875fa82e958f6c3ad942ef82193a9dd8ad67e2L56-R103)
[[3]](diffhunk://#diff-a3b1e68bfa29fbcfda7c703bbe875fa82e958f6c3ad942ef82193a9dd8ad67e2R112-R209)

* Added comprehensive unit tests in
`contrib/drivers/pgsql/pgsql_z_unit_convert_test.go` to verify type
mapping and conversion for all supported array types, including error
cases for invalid input.

### Utility and API Improvements

* Added a new `Bools()` method to the `gvar.Var` type in
`container/gvar/gvar_slice.go` for converting values to `[]bool`, with
corresponding unit tests in `container/gvar/gvar_z_unit_slice_test.go`.
[[1]](diffhunk://#diff-32e887e540e0170f785508d105cb794e4d54d854b53b6950973c80022973c490R11-R15)
[[2]](diffhunk://#diff-01453eca4d4b3e35d07ca105cb924c6441d0cd9df6cbcc337a89832c8d53057fR24-R41)

### SQL Formatting and Documentation

* Improved documentation and formatting in the upsert logic of
`contrib/drivers/pgsql/pgsql_format_upsert.go` to clarify the use of
`EXCLUDED` in PostgreSQL's `ON CONFLICT DO UPDATE`.
* Enhanced readability of the table field query in
`contrib/drivers/pgsql/pgsql_table_fields.go` by reformatting SQL and
clarifying field extraction.

---------

Co-authored-by: hailaz <739476267@qq.com>
Co-authored-by: houseme <housemecn@gmail.com>
2025-12-08 11:18:45 +08:00

180 lines
4.0 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 (
"testing"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/test/gtest"
"github.com/gogf/gf/contrib/drivers/pgsql/v2"
)
// Test_Open tests the Open method with various configurations
func Test_Open_WithNamespace(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Port: "5432",
Name: "test",
Namespace: "public",
}
db, err := driver.Open(config)
t.AssertNil(err)
t.AssertNE(db, nil)
if db != nil {
db.Close()
}
})
}
// Test_Open_WithTimezone tests Open with timezone configuration
func Test_Open_WithTimezone(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Port: "5432",
Name: "test",
Timezone: "Asia/Shanghai",
}
db, err := driver.Open(config)
t.AssertNil(err)
t.AssertNE(db, nil)
if db != nil {
db.Close()
}
})
}
// Test_Open_WithExtra tests Open with extra configuration
func Test_Open_WithExtra(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Port: "5432",
Name: "test",
Extra: "connect_timeout=10",
}
db, err := driver.Open(config)
t.AssertNil(err)
t.AssertNE(db, nil)
if db != nil {
db.Close()
}
})
}
// Test_Open_WithInvalidExtra tests Open with invalid extra configuration
func Test_Open_WithInvalidExtra(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Port: "5432",
Name: "test",
// Invalid extra format with invalid URL encoding that will cause parse error
Extra: "%Q=%Q&b",
}
_, err := driver.Open(config)
t.AssertNE(err, nil)
})
}
// Test_Open_WithFullConfig tests Open with all configuration options
func Test_Open_WithFullConfig(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Port: "5432",
Name: "test",
Namespace: "public",
Timezone: "UTC",
Extra: "connect_timeout=10",
}
db, err := driver.Open(config)
t.AssertNil(err)
t.AssertNE(db, nil)
if db != nil {
db.Close()
}
})
}
// Test_Open_WithoutPort tests Open without port
func Test_Open_WithoutPort(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Name: "test",
}
db, err := driver.Open(config)
t.AssertNil(err)
t.AssertNE(db, nil)
if db != nil {
db.Close()
}
})
}
// Test_Open_WithoutName tests Open without database name
func Test_Open_WithoutName(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "127.0.0.1",
Port: "5432",
}
db, err := driver.Open(config)
t.AssertNil(err)
t.AssertNE(db, nil)
if db != nil {
db.Close()
}
})
}
// Test_Open_InvalidHost tests Open with invalid host
func Test_Open_InvalidHost(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
driver := pgsql.Driver{}
config := &gdb.ConfigNode{
User: "postgres",
Pass: "12345678",
Host: "invalid_host_that_does_not_exist",
Port: "5432",
Name: "test",
}
// Note: sql.Open doesn't actually connect, so no error here
// The error would occur when actually using the connection
db, err := driver.Open(config)
t.AssertNil(err)
if db != nil {
db.Close()
}
})
}