github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/integration/sharding_insert_test.go (about) 1 // Copyright 2021 ecodeclub 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //go:build e2e 16 17 package integration 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 "time" 24 25 "github.com/ecodeclub/eorm" 26 "github.com/ecodeclub/eorm/internal/datasource/masterslave" 27 "github.com/ecodeclub/eorm/internal/test" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 "github.com/stretchr/testify/suite" 31 ) 32 33 type ShardingInsertTestSuite struct { 34 ShardingSuite 35 } 36 37 func (s *ShardingInsertTestSuite) TestInsert() { 38 t := s.T() 39 // db 是 2 分库 40 // table 是 3 分表 41 testCases := []struct { 42 name string 43 values []*test.OrderDetail 44 45 // 用来验证对应的数据库表里面有数据 46 // 其它数据库表没有数据 47 after func(t *testing.T) 48 wantErr error 49 wantAffected int64 50 }{ 51 { 52 name: "插入单条数据", 53 values: []*test.OrderDetail{ 54 // order_detail_db_1.order_detail_tab_1 55 { 56 OrderId: 1, 57 ItemId: 1, 58 }, 59 }, 60 61 // 受影响行数是1,然后又找到了这个数据,所以可以确保没有插入别的表 62 after: func(t *testing.T) { 63 od := s.findTgt(t, 1) 64 assert.Equal(t, test.OrderDetail{ 65 OrderId: 1, 66 ItemId: 1, 67 }, od) 68 }, 69 wantAffected: 1, 70 }, 71 { 72 name: "同库不同表", 73 values: []*test.OrderDetail{ 74 { 75 // order_detail_db_1.order_detail_tab_0 76 OrderId: 3, 77 ItemId: 1, 78 }, 79 { 80 // order_detail_db_1.order_detail_tab_0 81 OrderId: 5, 82 ItemId: 1, 83 }, 84 }, 85 after: func(t *testing.T) { 86 od3 := s.findTgt(t, 3) 87 assert.Equal(t, test.OrderDetail{ 88 OrderId: 3, 89 ItemId: 1, 90 }, od3) 91 od5 := s.findTgt(t, 5) 92 assert.Equal(t, test.OrderDetail{ 93 OrderId: 5, 94 ItemId: 1, 95 }, od5) 96 }, 97 wantAffected: 2, 98 }, 99 { 100 name: "不同库不同表", 101 values: []*test.OrderDetail{ 102 { 103 // order_detail_db_1.order_detail_tab_0 104 OrderId: 7, 105 ItemId: 1, 106 }, 107 { 108 // order_detail_db_1.order_detail_tab_0 109 OrderId: 9, 110 ItemId: 1, 111 }, 112 { 113 OrderId: 4, 114 ItemId: 2, 115 }, 116 }, 117 after: func(t *testing.T) { 118 od3 := s.findTgt(t, 7) 119 assert.Equal(t, test.OrderDetail{ 120 OrderId: 7, 121 ItemId: 1, 122 }, od3) 123 od5 := s.findTgt(t, 9) 124 assert.Equal(t, test.OrderDetail{ 125 OrderId: 9, 126 ItemId: 1, 127 }, od5) 128 od4 := s.findTgt(t, 4) 129 assert.Equal(t, test.OrderDetail{ 130 OrderId: 4, 131 ItemId: 2, 132 }, od4) 133 }, 134 wantAffected: 3, 135 }, 136 } 137 for _, tc := range testCases { 138 t.Run(tc.name, func(t *testing.T) { 139 res := eorm.NewShardingInsert[test.OrderDetail](s.shardingDB). 140 Values(tc.values).Exec(context.Background()) 141 affected, err := res.RowsAffected() 142 assert.Equal(t, tc.wantErr, err) 143 if err != nil { 144 return 145 } 146 assert.Equal(t, tc.wantAffected, affected) 147 tc.after(t) 148 }) 149 } 150 } 151 152 func (s *ShardingInsertTestSuite) findTgt(t *testing.T, orderID int64) test.OrderDetail { 153 dbName := fmt.Sprintf(s.DBPattern, orderID%2) 154 tabName := fmt.Sprintf(s.TablePattern, orderID%3) 155 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 156 defer cancel() 157 ds, _ := s.dataSources["root:root@tcp(localhost:13307).0"] 158 ctx = masterslave.UseMaster(ctx) 159 rows, err := ds.Query(ctx, eorm.Query{ 160 DB: "order_detail_db_1", 161 Datasource: "root:root@tcp(localhost:13307).0", 162 SQL: fmt.Sprintf("SELECT `order_id`, `item_id` FROM `%s`.`%s` WHERE order_id=%d", dbName, tabName, orderID), 163 }) 164 require.NoError(t, err) 165 defer rows.Close() 166 if !rows.Next() { 167 t.Fatal("no data") 168 } 169 var od test.OrderDetail 170 err = rows.Scan(&od.OrderId, &od.ItemId) 171 require.NoError(t, err) 172 return od 173 } 174 175 func TestMySQL8ShardingInsert(t *testing.T) { 176 suite.Run(t, &ShardingInsertTestSuite{ 177 ShardingSuite: newDefaultShardingSuite(), 178 }) 179 }