github.com/goravel/framework@v1.13.9/database/orm_test.go (about) 1 package database 2 3 import ( 4 "context" 5 "errors" 6 "log" 7 "testing" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/suite" 11 12 contractsorm "github.com/goravel/framework/contracts/database/orm" 13 "github.com/goravel/framework/database/gorm" 14 "github.com/goravel/framework/database/orm" 15 "github.com/goravel/framework/support/file" 16 ) 17 18 var connections = []contractsorm.Driver{ 19 contractsorm.DriverMysql, 20 contractsorm.DriverPostgresql, 21 contractsorm.DriverSqlite, 22 contractsorm.DriverSqlserver, 23 } 24 25 type contextKey int 26 27 const testContextKey contextKey = 0 28 29 type User struct { 30 orm.Model 31 orm.SoftDeletes 32 Name string 33 Avatar string 34 } 35 36 type OrmSuite struct { 37 suite.Suite 38 orm *OrmImpl 39 } 40 41 var ( 42 testMysqlQuery contractsorm.Query 43 testPostgresqlQuery contractsorm.Query 44 testSqliteQuery contractsorm.Query 45 testSqlserverDB contractsorm.Query 46 ) 47 48 func TestOrmSuite(t *testing.T) { 49 if testing.Short() { 50 t.Skip("Skipping tests of using docker") 51 } 52 53 mysqlDocker := gorm.NewMysqlDocker() 54 mysqlPool, mysqlResource, mysqlQuery, err := mysqlDocker.New() 55 if err != nil { 56 log.Fatalf("Get mysql error: %s", err) 57 } 58 testMysqlQuery = mysqlQuery 59 60 postgresqlDocker := gorm.NewPostgresqlDocker() 61 postgresqlPool, postgresqlResource, postgresqlQuery, err := postgresqlDocker.New() 62 if err != nil { 63 log.Fatalf("Get postgresql error: %s", err) 64 } 65 testPostgresqlQuery = postgresqlQuery 66 67 sqliteDocker := gorm.NewSqliteDocker("goravel") 68 _, _, sqliteQuery, err := sqliteDocker.New() 69 if err != nil { 70 log.Fatalf("Get sqlite error: %s", err) 71 } 72 testSqliteQuery = sqliteQuery 73 74 sqlserverDocker := gorm.NewSqlserverDocker() 75 sqlserverPool, sqlserverResource, sqlserverQuery, err := sqlserverDocker.New() 76 if err != nil { 77 log.Fatalf("Get sqlserver error: %s", err) 78 } 79 testSqlserverDB = sqlserverQuery 80 81 suite.Run(t, new(OrmSuite)) 82 83 assert.Nil(t, file.Remove("goravel")) 84 85 if err := mysqlPool.Purge(mysqlResource); err != nil { 86 log.Fatalf("Could not purge resource: %s", err) 87 } 88 if err := postgresqlPool.Purge(postgresqlResource); err != nil { 89 log.Fatalf("Could not purge resource: %s", err) 90 } 91 if err := sqlserverPool.Purge(sqlserverResource); err != nil { 92 log.Fatalf("Could not purge resource: %s", err) 93 } 94 95 } 96 97 func (s *OrmSuite) SetupTest() { 98 s.orm = &OrmImpl{ 99 connection: contractsorm.DriverMysql.String(), 100 ctx: context.Background(), 101 query: testMysqlQuery, 102 queries: map[string]contractsorm.Query{ 103 contractsorm.DriverMysql.String(): testMysqlQuery, 104 contractsorm.DriverPostgresql.String(): testPostgresqlQuery, 105 contractsorm.DriverSqlite.String(): testSqliteQuery, 106 contractsorm.DriverSqlserver.String(): testSqlserverDB, 107 }, 108 } 109 } 110 111 func (s *OrmSuite) TestConnection() { 112 for _, connection := range connections { 113 s.NotNil(s.orm.Connection(connection.String())) 114 } 115 } 116 117 func (s *OrmSuite) TestDB() { 118 db, err := s.orm.DB() 119 s.NotNil(db) 120 s.Nil(err) 121 122 for _, connection := range connections { 123 db, err := s.orm.Connection(connection.String()).DB() 124 s.NotNil(db) 125 s.Nil(err) 126 } 127 } 128 129 func (s *OrmSuite) TestQuery() { 130 s.NotNil(s.orm.Query()) 131 132 s.NotPanics(func() { 133 for i := 0; i < 5; i++ { 134 go func() { 135 var user User 136 _ = s.orm.Query().Find(&user, 1) 137 }() 138 } 139 }) 140 141 for _, connection := range connections { 142 s.NotNil(s.orm.Connection(connection.String()).Query()) 143 } 144 } 145 146 func (s *OrmSuite) TestFactory() { 147 s.NotNil(s.orm.Factory()) 148 149 for _, connection := range connections { 150 s.NotNil(s.orm.Connection(connection.String()).Factory()) 151 } 152 } 153 154 func (s *OrmSuite) TestObserve() { 155 s.orm.Observe(User{}, &UserObserver{}) 156 157 s.Equal([]orm.Observer{ 158 {Model: User{}, Observer: &UserObserver{}}, 159 }, orm.Observers) 160 161 for _, connection := range connections { 162 user := User{Name: "observer_name"} 163 s.EqualError(s.orm.Connection(connection.String()).Query().Create(&user), "error") 164 } 165 } 166 167 func (s *OrmSuite) TestTransactionSuccess() { 168 for _, connection := range connections { 169 user := User{Name: "transaction_success_user", Avatar: "transaction_success_avatar"} 170 user1 := User{Name: "transaction_success_user1", Avatar: "transaction_success_avatar1"} 171 s.Nil(s.orm.Connection(connection.String()).Transaction(func(tx contractsorm.Transaction) error { 172 s.Nil(tx.Create(&user)) 173 s.Nil(tx.Create(&user1)) 174 175 return nil 176 })) 177 178 var user2, user3 User 179 s.Nil(s.orm.Connection(connection.String()).Query().Find(&user2, user.ID)) 180 s.Nil(s.orm.Connection(connection.String()).Query().Find(&user3, user1.ID)) 181 } 182 } 183 184 func (s *OrmSuite) TestTransactionError() { 185 for _, connection := range connections { 186 s.NotNil(s.orm.Connection(connection.String()).Transaction(func(tx contractsorm.Transaction) error { 187 user := User{Name: "transaction_error_user", Avatar: "transaction_error_avatar"} 188 s.Nil(tx.Create(&user)) 189 190 user1 := User{Name: "transaction_error_user1", Avatar: "transaction_error_avatar1"} 191 s.Nil(tx.Create(&user1)) 192 193 return errors.New("error") 194 })) 195 196 var users []User 197 s.Nil(s.orm.Connection(connection.String()).Query().Find(&users)) 198 s.Equal(0, len(users)) 199 } 200 } 201 202 func (s *OrmSuite) TestWithContext() { 203 s.orm.Observe(User{}, &UserObserver{}) 204 ctx := context.WithValue(context.Background(), testContextKey, "with_context_goravel") 205 user := User{Name: "with_context_name"} 206 207 // Call Query directly 208 err := s.orm.WithContext(ctx).Query().Create(&user) 209 s.Nil(err) 210 s.Equal("with_context_name", user.Name) 211 s.Equal("with_context_goravel", user.Avatar) 212 213 // Call Connection, then call WithContext 214 for _, connection := range connections { 215 user.ID = 0 216 user.Avatar = "" 217 err := s.orm.Connection(connection.String()).WithContext(ctx).Query().Create(&user) 218 s.Nil(err) 219 s.Equal("with_context_name", user.Name) 220 s.Equal("with_context_goravel", user.Avatar) 221 } 222 223 // Call WithContext, then call Connection 224 for _, connection := range connections { 225 user.ID = 0 226 user.Avatar = "" 227 err := s.orm.WithContext(ctx).Connection(connection.String()).Query().Create(&user) 228 s.Nil(err) 229 s.Equal("with_context_name", user.Name) 230 s.Equal("with_context_goravel", user.Avatar) 231 } 232 } 233 234 type UserObserver struct{} 235 236 func (u *UserObserver) Retrieved(event contractsorm.Event) error { 237 return nil 238 } 239 240 func (u *UserObserver) Creating(event contractsorm.Event) error { 241 name := event.GetAttribute("name") 242 if name != nil { 243 if name.(string) == "observer_name" { 244 return errors.New("error") 245 } 246 if name.(string) == "with_context_name" { 247 if avatar := event.Context().Value(testContextKey); avatar != nil { 248 event.SetAttribute("avatar", avatar.(string)) 249 } 250 } 251 } 252 253 return nil 254 } 255 256 func (u *UserObserver) Created(event contractsorm.Event) error { 257 return nil 258 } 259 260 func (u *UserObserver) Updating(event contractsorm.Event) error { 261 return nil 262 } 263 264 func (u *UserObserver) Updated(event contractsorm.Event) error { 265 return nil 266 } 267 268 func (u *UserObserver) Saving(event contractsorm.Event) error { 269 return nil 270 } 271 272 func (u *UserObserver) Saved(event contractsorm.Event) error { 273 return nil 274 } 275 276 func (u *UserObserver) Deleting(event contractsorm.Event) error { 277 return nil 278 } 279 280 func (u *UserObserver) Deleted(event contractsorm.Event) error { 281 return nil 282 } 283 284 func (u *UserObserver) ForceDeleting(event contractsorm.Event) error { 285 return nil 286 } 287 288 func (u *UserObserver) ForceDeleted(event contractsorm.Event) error { 289 return nil 290 }