github.com/ecodeclub/eorm@v0.0.2-0.20231001112437-dae71da914d0/delete_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 package eorm 16 17 import ( 18 "context" 19 "database/sql" 20 "errors" 21 "fmt" 22 "testing" 23 24 "github.com/ecodeclub/eorm/internal/datasource/single" 25 26 "github.com/ecodeclub/eorm/internal/errs" 27 28 "github.com/DATA-DOG/go-sqlmock" 29 "github.com/stretchr/testify/require" 30 31 "github.com/stretchr/testify/assert" 32 ) 33 34 func TestDeleter_Build(t *testing.T) { 35 db := memoryDB() 36 testCases := []CommonTestCase{ 37 { 38 name: "no where", 39 builder: NewDeleter[TestModel](db).From(&TestModel{}), 40 wantSql: "DELETE FROM `test_model`;", 41 }, 42 { 43 name: "where", 44 builder: NewDeleter[TestModel](db).Where(C("Id").EQ(16)), 45 wantSql: "DELETE FROM `test_model` WHERE `id`=?;", 46 wantArgs: []interface{}{16}, 47 }, 48 { 49 name: "no where combination", 50 builder: NewDeleter[TestCombinedModel](db).From(&TestCombinedModel{}), 51 wantSql: "DELETE FROM `test_combined_model`;", 52 }, 53 { 54 name: "where combination", 55 builder: NewDeleter[TestCombinedModel](db).Where(C("CreateTime").EQ(uint64(1000))), 56 wantSql: "DELETE FROM `test_combined_model` WHERE `create_time`=?;", 57 wantArgs: []interface{}{uint64(1000)}, 58 }, 59 } 60 61 for _, tc := range testCases { 62 c := tc 63 t.Run(c.name, func(t *testing.T) { 64 query, err := c.builder.Build() 65 assert.Equal(t, c.wantErr, err) 66 assert.Equal(t, c.wantSql, query.SQL) 67 assert.Equal(t, c.wantArgs, query.Args) 68 }) 69 } 70 } 71 72 func TestDeleter_Exec(t *testing.T) { 73 testCases := []struct { 74 name string 75 mockOrder func(mock sqlmock.Sqlmock) 76 delete func(*sql.DB, *testing.T) Result 77 wantErr error 78 wantVal sql.Result 79 }{ 80 { 81 name: "exec err", 82 mockOrder: func(mock sqlmock.Sqlmock) { 83 mock.ExpectExec("DELETE FROM `test_model` WHERE `invalid`="). 84 WithArgs(1).WillReturnError(errs.NewInvalidFieldError("Invalid")) 85 }, 86 delete: func(db *sql.DB, t *testing.T) Result { 87 defer func(db *sql.DB) { _ = db.Close() }(db) 88 orm, err := OpenDS("mysql", single.NewDB(db)) 89 require.NoError(t, err) 90 deleter := NewDeleter[TestModel](orm) 91 result := deleter.From(&TestModel{}).Where(C("Invalid").EQ(1)).Exec(context.Background()) 92 return result 93 }, 94 wantErr: errs.NewInvalidFieldError("Invalid"), 95 }, 96 { 97 name: "直接删除", 98 mockOrder: func(mock sqlmock.Sqlmock) { 99 mock.ExpectExec("DELETE FROM `test_model` WHERE `id`=").WithArgs(1).WillReturnResult(sqlmock.NewResult(100, 1000)) 100 }, 101 delete: func(db *sql.DB, t *testing.T) Result { 102 defer func(db *sql.DB) { _ = db.Close() }(db) 103 orm, err := OpenDS("mysql", single.NewDB(db)) 104 require.NoError(t, err) 105 deleter := NewDeleter[TestModel](orm) 106 result := deleter.From(&TestModel{}).Where(C("Id").EQ(1)).Exec(context.Background()) 107 return result 108 }, 109 wantErr: nil, 110 wantVal: sqlmock.NewResult(100, 1000), 111 }, 112 { 113 name: "事务删除", 114 mockOrder: func(mock sqlmock.Sqlmock) { 115 mock.ExpectBegin() 116 mock.ExpectExec("DELETE FROM `test_model` WHERE `id`=").WithArgs(1).WillReturnResult(sqlmock.NewResult(10, 20)) 117 mock.ExpectCommit().WillReturnError(errors.New("commit 错误")) 118 }, 119 delete: func(db *sql.DB, t *testing.T) Result { 120 defer func(db *sql.DB) { _ = db.Close() }(db) 121 122 orm, err := OpenDS("mysql", single.NewDB(db)) 123 require.NoError(t, err) 124 tx, err := orm.BeginTx(context.Background(), &sql.TxOptions{}) 125 require.NoError(t, err) 126 127 deleter := NewDeleter[TestModel](tx) 128 result := deleter.From(&TestModel{}).Where(C("Id").EQ(1)).Exec(context.Background()) 129 require.NoError(t, result.Err()) 130 131 err = tx.Commit() 132 if err != nil { 133 return Result{err: err} 134 } 135 return result 136 }, 137 wantErr: errors.New("commit 错误"), 138 wantVal: sqlmock.NewResult(10, 20), 139 }, 140 } 141 142 for _, tc := range testCases { 143 t.Run(tc.name, func(t *testing.T) { 144 mockDB, mock, err := sqlmock.New() 145 if err != nil { 146 t.Fatal(err) 147 } 148 tc.mockOrder(mock) 149 result := tc.delete(mockDB, t) 150 151 assert.Equal(t, tc.wantErr, result.Err()) 152 153 if result.Err() != nil { 154 return 155 } 156 157 rowsAffectedExpect, err := tc.wantVal.RowsAffected() 158 require.NoError(t, err) 159 rowsAffected, err := result.RowsAffected() 160 require.NoError(t, err) 161 assert.Equal(t, rowsAffectedExpect, rowsAffected) 162 163 lastInsertIdExpected, err := tc.wantVal.LastInsertId() 164 require.NoError(t, err) 165 lastInsertId, err := result.LastInsertId() 166 require.NoError(t, err) 167 assert.Equal(t, lastInsertIdExpected, lastInsertId) 168 169 if err = mock.ExpectationsWereMet(); err != nil { 170 t.Error(err) 171 } 172 }) 173 } 174 } 175 176 func ExampleDeleter_Build() { 177 db := memoryDB() 178 query, _ := NewDeleter[TestModel](db).From(&TestModel{}).Build() 179 fmt.Printf("SQL: %s", query.SQL) 180 // Output: 181 // SQL: DELETE FROM `test_model`; 182 } 183 184 func ExampleDeleter_From() { 185 db := memoryDB() 186 query, _ := NewDeleter[TestModel](db).From(&TestModel{}).Build() 187 fmt.Printf("SQL: %s", query.SQL) 188 // Output: 189 // SQL: DELETE FROM `test_model`; 190 } 191 192 func ExampleDeleter_Where() { 193 db := memoryDB() 194 query, _ := NewDeleter[TestModel](db).Where(C("Id").EQ(12)).Build() 195 fmt.Printf("SQL: %s\nArgs: %v", query.SQL, query.Args) 196 // Output: 197 // SQL: DELETE FROM `test_model` WHERE `id`=?; 198 // Args: [12] 199 }