github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/internal/integration/sharding_single_transaction_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 "database/sql" 22 "testing" 23 24 "github.com/ecodeclub/eorm/internal/datasource/masterslave" 25 "github.com/ecodeclub/eorm/internal/datasource/transaction" 26 27 "github.com/ecodeclub/eorm" 28 "github.com/ecodeclub/eorm/internal/test" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/require" 31 "github.com/stretchr/testify/suite" 32 ) 33 34 type ShardingSingleTxTestSuite struct { 35 ShardingSelectUpdateInsertSuite 36 } 37 38 func (s *ShardingSingleTxTestSuite) TestDoubleShardingSelect() { 39 t := s.T() 40 testCases := []struct { 41 name string 42 querySet []*test.OrderDetail 43 txFunc func(t *testing.T) *eorm.Tx 44 }{ 45 { 46 name: "double select", 47 querySet: []*test.OrderDetail{ 48 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 49 }, 50 txFunc: func(t *testing.T) *eorm.Tx { 51 tx, er := s.shardingDB.BeginTx( 52 transaction.UsingTxType(context.Background(), transaction.Single), &sql.TxOptions{}) 53 require.NoError(t, er) 54 return tx 55 }, 56 }, 57 } 58 for _, tc := range testCases { 59 t.Run(tc.name, func(t *testing.T) { 60 tx := tc.txFunc(t) 61 defer tx.Commit() 62 querySet, err := eorm.NewShardingSelector[test.OrderDetail](tx). 63 Where(eorm.C("OrderId").EQ(123)). 64 GetMulti(masterslave.UseMaster(context.Background())) 65 require.NoError(t, err) 66 assert.ElementsMatch(t, tc.querySet, querySet) 67 68 querySet, err = eorm.NewShardingSelector[test.OrderDetail](tx). 69 Where(eorm.C("OrderId").EQ(123)). 70 GetMulti(masterslave.UseMaster(context.Background())) 71 require.NoError(t, err) 72 assert.ElementsMatch(t, tc.querySet, querySet) 73 }) 74 } 75 } 76 77 func (s *ShardingSingleTxTestSuite) TestShardingSelectInsert_Commit_Or_Rollback() { 78 t := s.T() 79 testCases := []struct { 80 name string 81 wantAffected int64 82 values []*test.OrderDetail 83 querySet []*test.OrderDetail 84 txFunc func(t *testing.T) *eorm.Tx 85 afterFunc func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) 86 }{ 87 { 88 name: "select insert commit", 89 wantAffected: 1, 90 values: []*test.OrderDetail{ 91 {OrderId: 33, ItemId: 100, UsingCol1: "Nikolai", UsingCol2: "Jokic"}, 92 }, 93 querySet: []*test.OrderDetail{ 94 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 95 }, 96 txFunc: func(t *testing.T) *eorm.Tx { 97 tx, er := s.shardingDB.BeginTx( 98 transaction.UsingTxType(context.Background(), transaction.Single), &sql.TxOptions{}) 99 require.NoError(t, er) 100 return tx 101 }, 102 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 103 err := tx.Commit() 104 require.NoError(t, err) 105 106 queryVal := s.findTgt(t, values) 107 assert.ElementsMatch(t, values, queryVal) 108 }, 109 }, 110 { 111 name: "select insert rollback", 112 wantAffected: 1, 113 values: []*test.OrderDetail{ 114 {OrderId: 199, ItemId: 100, UsingCol1: "Jason", UsingCol2: "Tatum"}, 115 }, 116 querySet: []*test.OrderDetail{ 117 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 118 }, 119 txFunc: func(t *testing.T) *eorm.Tx { 120 tx, er := s.shardingDB.BeginTx( 121 transaction.UsingTxType(context.Background(), transaction.Single), &sql.TxOptions{}) 122 require.NoError(t, er) 123 return tx 124 }, 125 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 126 var wantOds []*test.OrderDetail 127 err := tx.Rollback() 128 require.NoError(t, err) 129 130 queryVal := s.findTgt(t, values) 131 assert.ElementsMatch(t, wantOds, queryVal) 132 }, 133 }, 134 } 135 for _, tc := range testCases { 136 t.Run(tc.name, func(t *testing.T) { 137 tx := tc.txFunc(t) 138 querySet, err := eorm.NewShardingSelector[test.OrderDetail](tx). 139 Where(eorm.C("OrderId").EQ(123)). 140 GetMulti(masterslave.UseMaster(context.Background())) 141 require.NoError(t, err) 142 assert.ElementsMatch(t, tc.querySet, querySet) 143 res := eorm.NewShardingInsert[test.OrderDetail](tx). 144 Values(tc.values).Exec(context.Background()) 145 affected, err := res.RowsAffected() 146 require.NoError(t, err) 147 assert.Equal(t, tc.wantAffected, affected) 148 tc.afterFunc(t, tx, tc.values) 149 }) 150 } 151 } 152 153 func (s *ShardingSingleTxTestSuite) TestShardingSelectUpdate_Commit_Or_Rollback() { 154 t := s.T() 155 testCases := []struct { 156 name string 157 wantAffected int64 158 target *test.OrderDetail 159 upPre eorm.Predicate 160 querySet []*test.OrderDetail 161 upQuerySet []*test.OrderDetail 162 txFunc func(t *testing.T) *eorm.Tx 163 afterFunc func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) 164 }{ 165 { 166 name: "select update where eq commit", 167 upPre: eorm.C("OrderId").EQ(11), 168 wantAffected: 1, 169 target: &test.OrderDetail{UsingCol1: "ben"}, 170 querySet: []*test.OrderDetail{ 171 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 172 }, 173 upQuerySet: []*test.OrderDetail{ 174 {OrderId: 11, ItemId: 8, UsingCol1: "ben", UsingCol2: "Harden"}, 175 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 176 }, 177 txFunc: func(t *testing.T) *eorm.Tx { 178 tx, er := s.shardingDB.BeginTx( 179 transaction.UsingTxType(context.Background(), transaction.Single), &sql.TxOptions{}) 180 require.NoError(t, er) 181 return tx 182 }, 183 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 184 err := tx.Commit() 185 require.NoError(t, err) 186 187 queryVal := s.findTgt(t, values) 188 assert.ElementsMatch(t, values, queryVal) 189 }, 190 }, 191 { 192 name: "select update rollback", 193 upPre: eorm.C("OrderId").EQ(181), 194 wantAffected: 1, 195 target: &test.OrderDetail{UsingCol1: "Jordan"}, 196 querySet: []*test.OrderDetail{ 197 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 198 }, 199 upQuerySet: []*test.OrderDetail{ 200 {OrderId: 181, ItemId: 11, UsingCol1: "Kawhi", UsingCol2: "Leonard"}, 201 {OrderId: 123, ItemId: 10, UsingCol1: "LeBron", UsingCol2: "James"}, 202 }, 203 txFunc: func(t *testing.T) *eorm.Tx { 204 tx, er := s.shardingDB.BeginTx( 205 transaction.UsingTxType(context.Background(), transaction.Single), &sql.TxOptions{}) 206 require.NoError(t, er) 207 return tx 208 }, 209 afterFunc: func(t *testing.T, tx *eorm.Tx, values []*test.OrderDetail) { 210 err := tx.Rollback() 211 require.NoError(t, err) 212 213 queryVal := s.findTgt(t, values) 214 assert.ElementsMatch(t, values, queryVal) 215 }, 216 }, 217 } 218 for _, tc := range testCases { 219 t.Run(tc.name, func(t *testing.T) { 220 tx := tc.txFunc(t) 221 querySet, err := eorm.NewShardingSelector[test.OrderDetail](tx). 222 Where(eorm.C("OrderId").EQ(123)). 223 GetMulti(masterslave.UseMaster(context.Background())) 224 require.NoError(t, err) 225 assert.ElementsMatch(t, tc.querySet, querySet) 226 res := eorm.NewShardingUpdater[test.OrderDetail](tx).Update(tc.target). 227 Set(eorm.C("UsingCol1")).Where(tc.upPre).Exec(context.Background()) 228 affected, err := res.RowsAffected() 229 require.NoError(t, err) 230 assert.Equal(t, tc.wantAffected, affected) 231 tc.afterFunc(t, tx, tc.upQuerySet) 232 }) 233 } 234 } 235 236 func TestMySQL8ShardingSingleTxTestSuite(t *testing.T) { 237 suite.Run(t, &ShardingSingleTxTestSuite{ 238 ShardingSelectUpdateInsertSuite: newShardingSelectUpdateInsertSuite(), 239 }) 240 }