Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add function Partition for Model of package gdb #2989

Merged
merged 6 commits into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 70 additions & 5 deletions contrib/drivers/mysql/mysql__test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package mysql_test
import (
"context"
"fmt"
"testing"

"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/database/gdb"
Expand All @@ -22,6 +23,7 @@ const (
TableName = "user"
TestSchema1 = "test1"
TestSchema2 = "test2"
TestPartitionDB = "test3"
TableNamePrefix1 = "gf_"
TestDbUser = "root"
TestDbPass = "12345678"
Expand All @@ -31,28 +33,33 @@ const (
var (
db gdb.DB
db2 gdb.DB
db3 gdb.DB
dbPrefix gdb.DB
dbInvalid gdb.DB
ctx = context.TODO()
)

func init() {
nodeDefault := gdb.ConfigNode{
Link: "mysql:root:12345678@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true",
Link: fmt.Sprintf("mysql:root:%s@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true", TestDbPass),
}
partitionDefault := gdb.ConfigNode{
Link: fmt.Sprintf("mysql:root:%s@tcp(127.0.0.1:3307)/?loc=Local&parseTime=true", TestDbPass),
Debug: true,
}

nodePrefix := gdb.ConfigNode{
Link: "mysql:root:12345678@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true",
Link: fmt.Sprintf("mysql:root:%s@tcp(127.0.0.1:3306)/?loc=Local&parseTime=true", TestDbPass),
}
nodePrefix.Prefix = TableNamePrefix1

nodeInvalid := gdb.ConfigNode{
Link: "mysql:root:12345678@tcp(127.0.0.1:3307)/?loc=Local&parseTime=true",
Link: fmt.Sprintf("mysql:root:%s@tcp(127.0.0.1:3307)/?loc=Local&parseTime=true", TestDbPass),
}

gdb.AddConfigNode("test", nodeDefault)
gdb.AddConfigNode("prefix", nodePrefix)
gdb.AddConfigNode("nodeinvalid", nodeInvalid)
gdb.AddConfigNode("partition", partitionDefault)
gdb.AddConfigNode(gdb.DefaultGroupName, nodeDefault)

// Default db.
Expand All @@ -68,9 +75,12 @@ 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)

db3 = db.Schema(TestPartitionDB)
// Prefix db.
if r, err := gdb.NewByGroup("prefix"); err != nil {
gtest.Error(err)
Expand Down Expand Up @@ -156,3 +166,58 @@ 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)
}
}
11 changes: 11 additions & 0 deletions database/gdb/gdb_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Model struct {
limit int // Used for "select ... start, limit ..." statement.
option int // Option for extra operation features.
offset int // Offset statement for some databases grammar.
partition string // Partition table partition name.
data interface{} // Data for operation, which can be type of map/[]map/struct/*struct/string, etc.
batch int // Batch number for batch Insert/Replace/Save operations.
filter bool // Filter data and where key-value pairs according to the fields of the table.
Expand Down Expand Up @@ -174,6 +175,16 @@ func (c *Core) With(objects ...interface{}) *Model {
return c.db.Model().With(objects...)
}

// Partition sets Partition name.
// Example:
// dao.User.Ctx(ctx).Partition(“p1","p2").All()

arieslee marked this conversation as resolved.
Show resolved Hide resolved
func (m *Model) Partition(partitions ...string) *Model {
model := m.getModel()
model.partition = gstr.Join(partitions, ",")
return model
}

// Model acts like Core.Model except it operates on transaction.
// See Core.Model.
func (tx *TXCore) Model(tableNameQueryOrStruct ...interface{}) *Model {
Expand Down
Loading