test(contrib/drivers/mariadb): add infrastructure, core and model tests (#4719)

## Summary

- Add full test infrastructure (`mariadb_unit_init_test.go`) with
MariaDB-specific helpers (createTable, createInitTable, dropTable)
matching the MySQL test baseline
- Port 4 basic tests from MySQL: `Test_New`, `Test_DB_Ping`,
`Test_DB_Query`, `Test_DB_Exec`
- Port 47 core tests covering CRUD operations, raw SQL, schema
switching, and DB/TX method parity
- Port 55 model tests covering Model API: Fields, Where, Scan, Save,
Replace, InsertIgnore, InsertGetId, OmitEmpty, Distinct,
Count/Min/Max/Avg/Sum, HasField, chained operations, testdata SQL-based
scenarios and more
- Add 5 testdata SQL files required by model tests (copied from MySQL
baseline)

All tests are structurally identical to the MySQL driver baseline. SQL
syntax is standard and shared. Package and import references are adapted
for MariaDB.

ref #4689

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Jack Ling
2026-03-24 17:50:05 +08:00
committed by GitHub
parent 766579d868
commit 68b02218d7
8 changed files with 4413 additions and 15 deletions

View File

@ -9,6 +9,7 @@ package mariadb_test
import (
"context"
"fmt"
"testing"
"time"
_ "github.com/gogf/gf/contrib/drivers/mariadb/v2"
@ -21,17 +22,22 @@ import (
)
const (
TableSize = 10
TableName = "user"
TestSchema1 = "test1"
TestSchema2 = "test2"
TestDbPass = "12345678"
CreateTime = "2018-10-24 10:00:00"
TableSize = 10
TableName = "user"
TestSchema1 = "test1"
TestSchema2 = "test2"
TestPartitionDB = "test3"
TableNamePrefix1 = "gf_"
TestDbUser = "root"
TestDbPass = "12345678"
CreateTime = "2018-10-24 10:00:00"
)
var (
db gdb.DB
db2 gdb.DB
db3 gdb.DB
dbPrefix gdb.DB
dbInvalid gdb.DB
ctx = context.TODO()
)
@ -42,10 +48,26 @@ func init() {
Link: fmt.Sprintf("mariadb:root:%s@tcp(127.0.0.1:3307)/?loc=Local&parseTime=true", TestDbPass),
TranTimeout: time.Second * 3,
}
err := gdb.AddConfigNode(gdb.DefaultGroupName, nodeDefault)
if err != nil {
panic(err)
partitionDefault := gdb.ConfigNode{
Link: fmt.Sprintf("mariadb:root:%s@tcp(127.0.0.1:3307)/?loc=Local&parseTime=true", TestDbPass),
Debug: true,
TranTimeout: time.Second * 3,
}
nodePrefix := gdb.ConfigNode{
Link: fmt.Sprintf("mariadb:root:%s@tcp(127.0.0.1:3307)/?loc=Local&parseTime=true", TestDbPass),
TranTimeout: time.Second * 3,
}
nodePrefix.Prefix = TableNamePrefix1
nodeInvalid := gdb.ConfigNode{
Link: fmt.Sprintf("mariadb:root:%s@tcp(127.0.0.1:3317)/?loc=Local&parseTime=true", TestDbPass),
TranTimeout: time.Second * 3,
}
gdb.AddConfigNode("test", nodeDefault)
gdb.AddConfigNode("prefix", nodePrefix)
gdb.AddConfigNode("nodeinvalid", nodeInvalid)
gdb.AddConfigNode("partition", partitionDefault)
gdb.AddConfigNode(gdb.DefaultGroupName, nodeDefault)
// Default db.
if r, err := gdb.NewByGroup(); err != nil {
@ -60,15 +82,27 @@ func init() {
if _, err := db.Exec(ctx, fmt.Sprintf(schemaTemplate, TestSchema2)); err != nil {
gtest.Error(err)
}
if _, err := db.Exec(ctx, fmt.Sprintf(schemaTemplate, TestPartitionDB)); err != nil {
gtest.Error(err)
}
db = db.Schema(TestSchema1)
db2 = db.Schema(TestSchema2)
// Invalid db (wrong port for testing error handling).
nodeInvalid := gdb.ConfigNode{
Link: fmt.Sprintf("mariadb:root:%s@tcp(127.0.0.1:3317)/?loc=Local&parseTime=true", TestDbPass),
TranTimeout: time.Second * 3,
db3 = db.Schema(TestPartitionDB)
// Prefix db.
if r, err := gdb.NewByGroup("prefix"); err != nil {
gtest.Error(err)
} else {
dbPrefix = r
}
gdb.AddConfigNode("nodeinvalid", nodeInvalid)
if _, err := dbPrefix.Exec(ctx, fmt.Sprintf(schemaTemplate, TestSchema1)); err != nil {
gtest.Error(err)
}
if _, err := dbPrefix.Exec(ctx, fmt.Sprintf(schemaTemplate, TestSchema2)); err != nil {
gtest.Error(err)
}
dbPrefix = dbPrefix.Schema(TestSchema1)
// Invalid db.
if r, err := gdb.NewByGroup("nodeinvalid"); err != nil {
gtest.Error(err)
} else {
@ -140,3 +174,61 @@ func dropTableWithDb(db gdb.DB, table string) {
gtest.Error(err)
}
}
func Test_PartitionTable(t *testing.T) {
dropShopDBTable()
createShopDBTable()
insertShopDBData()
// defer dropShopDBTable()
gtest.C(t, func(t *gtest.T) {
data, err := db3.Ctx(ctx).Model("dbx_order").Partition("p3", "p4").All()
t.AssertNil(err)
dataLen := len(data)
t.Assert(dataLen, 5)
data, err = db3.Ctx(ctx).Model("dbx_order").Partition("p3").All()
t.AssertNil(err)
dataLen = len(data)
t.Assert(dataLen, 5)
})
}
func createShopDBTable() {
sql := `CREATE TABLE dbx_order (
id int(11) NOT NULL,
sales_date date DEFAULT NULL,
amount decimal(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (YEAR(sales_date))
(PARTITION p1 VALUES LESS THAN (2020) ENGINE = InnoDB,
PARTITION p2 VALUES LESS THAN (2021) ENGINE = InnoDB,
PARTITION p3 VALUES LESS THAN (2022) ENGINE = InnoDB,
PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB);`
_, err := db3.Exec(ctx, sql)
if err != nil {
gtest.Fatal(err.Error())
}
}
func insertShopDBData() {
data := g.Slice{}
year := 2020
for i := 1; i <= 5; i++ {
year++
data = append(data, g.Map{
"id": i,
"sales_date": fmt.Sprintf("%d-09-21", year),
"amount": fmt.Sprintf("1%d.21", i),
})
}
_, err := db3.Model("dbx_order").Ctx(ctx).Data(data).Insert()
if err != nil {
gtest.Error(err)
}
}
func dropShopDBTable() {
if _, err := db3.Exec(ctx, "DROP TABLE IF EXISTS `dbx_order`"); err != nil {
gtest.Error(err)
}
}

View File

@ -0,0 +1,83 @@
// 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 mariadb_test
import (
"context"
"testing"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/test/gtest"
)
func Test_Instance(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
_, err := gdb.Instance("none")
t.AssertNE(err, nil)
db, err := gdb.Instance()
t.AssertNil(err)
err1 := db.PingMaster()
err2 := db.PingSlave()
t.Assert(err1, nil)
t.Assert(err2, nil)
})
}
func Test_Func_FormatSqlWithArgs(t *testing.T) {
// mysql
gtest.C(t, func(t *gtest.T) {
var s string
s = gdb.FormatSqlWithArgs("select * from table where id>=? and sex=?", []any{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
// mssql
gtest.C(t, func(t *gtest.T) {
var s string
s = gdb.FormatSqlWithArgs("select * from table where id>=@p1 and sex=@p2", []any{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
// pgsql
gtest.C(t, func(t *gtest.T) {
var s string
s = gdb.FormatSqlWithArgs("select * from table where id>=$1 and sex=$2", []any{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
// oracle
gtest.C(t, func(t *gtest.T) {
var s string
s = gdb.FormatSqlWithArgs("select * from table where id>=:v1 and sex=:v2", []any{100, 1})
t.Assert(s, "select * from table where id>=100 and sex=1")
})
}
func Test_Func_ToSQL(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
sql, err := gdb.ToSQL(ctx, func(ctx context.Context) error {
value, err := db.Ctx(ctx).Model(TableName).Fields("nickname").Where("id", 1).Value()
t.Assert(value, nil)
return err
})
t.AssertNil(err)
t.Assert(sql, "SELECT `nickname` FROM `user` WHERE `id`=1 LIMIT 1")
})
}
func Test_Func_CatchSQL(t *testing.T) {
table := createInitTable()
defer dropTable(table)
gtest.C(t, func(t *gtest.T) {
array, err := gdb.CatchSQL(ctx, func(ctx context.Context) error {
value, err := db.Ctx(ctx).Model(table).Fields("nickname").Where("id", 1).Value()
t.Assert(value, "name_1")
return err
})
t.AssertNil(err)
t.AssertGE(len(array), 1)
})
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
CREATE TABLE `date_time_example` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`year` year DEFAULT NULL COMMENT 'year',
`date` date DEFAULT NULL COMMENT 'Date',
`time` time DEFAULT NULL COMMENT 'time',
`datetime` datetime DEFAULT NULL COMMENT 'datetime',
`timestamp` timestamp NULL DEFAULT NULL COMMENT 'Timestamp',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

View File

@ -0,0 +1,9 @@
CREATE TABLE IF NOT EXISTS `employee`
(
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
age INT NOT NULL
);
INSERT INTO employee(name, age) VALUES ('John', 30);
INSERT INTO employee(name, age) VALUES ('Mary', 28);

View File

@ -0,0 +1,20 @@
CREATE TABLE %s (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`key` varchar(45) DEFAULT NULL,
`category_id` int(10) unsigned NOT NULL,
`user_id` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`content` mediumtext NOT NULL,
`sort` int(10) unsigned DEFAULT '0',
`brief` varchar(255) DEFAULT NULL,
`thumb` varchar(255) DEFAULT NULL,
`tags` varchar(900) DEFAULT NULL,
`referer` varchar(255) DEFAULT NULL,
`status` smallint(5) unsigned DEFAULT '0',
`view_count` int(10) unsigned DEFAULT '0',
`zan_count` int(10) unsigned DEFAULT NULL,
`cai_count` int(10) unsigned DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -1570,6 +1570,7 @@ func Test_DB_Ctx(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
_, err := db.Query(ctx, "SELECT SLEEP(10)")
t.AssertNE(err, nil)
t.Assert(gstr.Contains(err.Error(), "deadline"), true)
})
}