github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/kit/sqlx/database_test.go (about) 1 package sqlx_test 2 3 import ( 4 "context" 5 "database/sql/driver" 6 "testing" 7 "time" 8 9 // . "github.com/onsi/gomega" 10 11 "github.com/machinefi/w3bstream/pkg/depends/base/types" 12 "github.com/machinefi/w3bstream/pkg/depends/conf/log" 13 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/builder" 14 ) 15 16 var connectors map[string]driver.Connector 17 18 func init() { 19 connectors = make(map[string]driver.Connector) 20 // TODO add other database connector for testing 21 // mysqlConnector = &mysql.MysqlConnector{ 22 // Host: "root@tcp(0.0.0.0:3306)", 23 // Extra: "charset=utf8mb4&parseTime=true&interpolateParams=true&autocommit=true&loc=Local", 24 // } 25 26 // postgres 27 /* 28 { 29 ep := postgrestestutil.Endpoint 30 connectors["postgres"] = &postgres.Connector{ 31 Extra: "sslmode=disable", 32 Extensions: []string{"postgis"}, 33 Host: fmt.Sprintf( 34 "postgresql://%s:%s@127.0.0.1:5432", 35 ep.Master.Username, ep.Master.Password, 36 ), 37 } 38 } 39 */ 40 } 41 42 func Background() context.Context { 43 return log.WithLogger(context.Background(), log.Std()) 44 } 45 46 type OperateTime struct { 47 CreatedAt types.Datetime `db:"f_created_at,default=CURRENT_TIMESTAMP,onupdate=CURRENT_TIMESTAMP"` 48 UpdatedAt int64 `db:"f_updated_at,default='0'"` 49 } 50 51 type Gender int 52 53 const ( 54 GenderMale Gender = iota + 1 55 GenderFemale 56 ) 57 58 func (Gender) EnumType() string { 59 return "Gender" 60 } 61 62 func (Gender) Enums() map[int][]string { 63 return map[int][]string{ 64 int(GenderMale): {"male", "男"}, 65 int(GenderFemale): {"female", "女"}, 66 } 67 } 68 69 func (g Gender) String() string { 70 switch g { 71 case GenderMale: 72 return "male" 73 case GenderFemale: 74 return "female" 75 } 76 return "" 77 } 78 79 type User struct { 80 ID uint64 `db:"f_id,autoincrement"` 81 Name string `db:"f_name,size=255,default=''"` 82 Nickname string `db:"f_nickname,size=255,default=''"` 83 Username string `db:"f_username,default=''"` 84 Gender Gender `db:"f_gender,default='0'"` 85 86 OperateTime 87 } 88 89 func (user *User) Comments() map[string]string { 90 return map[string]string{ 91 "Name": "姓名", 92 } 93 } 94 95 func (user *User) TableName() string { 96 return "t_user" 97 } 98 99 func (user *User) PrimaryKey() []string { 100 return []string{"ID"} 101 } 102 103 func (user *User) Indexes() builder.Indexes { 104 return builder.Indexes{ 105 "i_nickname": {"Nickname"}, 106 } 107 } 108 109 func (user *User) UniqueIndexes() builder.Indexes { 110 return builder.Indexes{ 111 "i_name": {"Name"}, 112 } 113 } 114 115 type User2 struct { 116 ID uint64 `db:"f_id,autoincrement"` 117 Nickname string `db:"f_nickname,size=255,default=''"` 118 Gender Gender `db:"f_gender,default='0'"` 119 Name string `db:"f_name,deprecated=f_real_name"` 120 RealName string `db:"f_real_name,size=255,default=''"` 121 Age int32 `db:"f_age,default='0'"` 122 Username string `db:"f_username,deprecated"` 123 } 124 125 func (user *User2) TableName() string { 126 return "t_user" 127 } 128 129 func (user *User2) PrimaryKey() []string { 130 return []string{"ID"} 131 } 132 133 func (user *User2) Indexes() builder.Indexes { 134 return builder.Indexes{ 135 "i_nickname": {"Nickname"}, 136 } 137 } 138 139 func (user *User2) UniqueIndexes() builder.Indexes { 140 return builder.Indexes{ 141 "i_name": {"RealName"}, 142 } 143 } 144 145 func DISABLED_TestMigrate(t *testing.T) { 146 /* 147 os.Setenv("PROJECT_FEATURE", "test1") 148 defer func() { 149 os.Remove("PROJECT_FEATURE") 150 }() 151 152 dbTest := sqlx.NewDatabase("test_for_migrate") 153 154 for name, connector := range connectors { 155 t.Run(name, func(t *testing.T) { 156 for _, schema := range []string{"import", "public", "backup"} { 157 dbTest.Tables.Range(func(table *builder.Table, idx int) { 158 db := dbTest.OpenDB(connector).WithSchema(schema) 159 _, _ = db.Exec(db.Dialect().DropTable(table)) 160 }) 161 162 t.Run("CreateTable_"+schema, func(t *testing.T) { 163 dbTest.Register(&User{}) 164 db := dbTest.OpenDB(connector).WithSchema(schema) 165 166 t.Run("First", func(t *testing.T) { 167 err := migration.Migrate(db, nil) 168 NewWithT(t).Expect(err).To(BeNil()) 169 }) 170 171 t.Run("Again", func(t *testing.T) { 172 _ = migration.Migrate(db, os.Stdout) 173 err := migration.Migrate(db, nil) 174 NewWithT(t).Expect(err).To(BeNil()) 175 }) 176 }) 177 178 t.Run("NoMigrate_"+schema, func(t *testing.T) { 179 dbTest.Register(&User{}) 180 db := dbTest.OpenDB(connector).WithSchema(schema) 181 err := migration.Migrate(db, nil) 182 NewWithT(t).Expect(err).To(BeNil()) 183 184 t.Run("migrate to user2", func(t *testing.T) { 185 dbTest.Register(&User2{}) 186 db := dbTest.OpenDB(connector).WithSchema(schema) 187 err := migration.Migrate(db, nil) 188 NewWithT(t).Expect(err).To(BeNil()) 189 }) 190 191 t.Run("migrate to user2 again", func(t *testing.T) { 192 dbTest.Register(&User2{}) 193 db := dbTest.OpenDB(connector).WithSchema(schema) 194 err := migration.Migrate(db, nil) 195 NewWithT(t).Expect(err).To(BeNil()) 196 }) 197 }) 198 199 t.Run("MigrateToUser_"+schema, func(t *testing.T) { 200 db := dbTest.OpenDB(connector).WithSchema(schema) 201 err := migration.Migrate(db, os.Stdout) 202 NewWithT(t).Expect(err).To(BeNil()) 203 err = migration.Migrate(db, nil) 204 NewWithT(t).Expect(err).To(BeNil()) 205 }) 206 207 dbTest.Tables.Range(func(table *builder.Table, idx int) { 208 db := dbTest.OpenDB(connector).WithSchema(schema) 209 _, _ = db.Exec(db.Dialect().DropTable(table)) 210 }) 211 } 212 }) 213 } 214 */ 215 } 216 217 func DISABLED_TestCRUD(t *testing.T) { 218 /* 219 dbTest := sqlx.NewDatabase("test_crud") 220 221 for name, connector := range connectors { 222 t.Run(name, func(t *testing.T) { 223 d := dbTest.OpenDB(connector) 224 db := d.WithContext(metax.ContextWithMeta(d.Context(), metax.ParseMeta("_id=11111"))) 225 userTable := dbTest.Register(&User{}) 226 err := migration.Migrate(db, nil) 227 228 NewWithT(t).Expect(err).To(BeNil()) 229 230 t.Run("InsertSingle", func(t *testing.T) { 231 user := User{ 232 Name: uuid.New().String(), 233 Gender: GenderMale, 234 } 235 236 t.Run("Canceled", func(t *testing.T) { 237 ctx, cancel := context.WithCancel(Background()) 238 db2 := db.WithContext(ctx) 239 240 go func() { 241 time.Sleep(5 * time.Millisecond) 242 cancel() 243 }() 244 245 err := sqlx.NewTasks(db2). 246 With( 247 func(db sqlx.DBExecutor) error { 248 _, err := db.Exec(sqlx.InsertToDB(db, &user, nil)) 249 return err 250 }, 251 func(db sqlx.DBExecutor) error { 252 time.Sleep(10 * time.Millisecond) 253 return nil 254 }, 255 ). 256 Do() 257 258 NewWithT(t).Expect(err).NotTo(BeNil()) 259 }) 260 261 _, err := db.Exec(sqlx.InsertToDB(db, &user, nil)) 262 NewWithT(t).Expect(err).To(BeNil()) 263 264 t.Run("Update", func(t *testing.T) { 265 user.Gender = GenderFemale 266 _, err := db.Exec( 267 builder.Update(dbTest.T(&user)). 268 Set(sqlx.AsAssignments(db, &user)...). 269 Where( 270 userTable.ColByFieldName("Name").Eq(user.Name), 271 ), 272 ) 273 NewWithT(t).Expect(err).To(BeNil()) 274 }) 275 t.Run("Select", func(t *testing.T) { 276 userForSelect := User{} 277 err := db.QueryAndScan( 278 builder.Select(nil).From( 279 userTable, 280 builder.Where(userTable.ColByFieldName("Name").Eq(user.Name)), 281 builder.Comment("FindUser"), 282 ), 283 &userForSelect) 284 285 NewWithT(t).Expect(err).To(BeNil()) 286 287 NewWithT(t).Expect(user.Name).To(Equal(userForSelect.Name)) 288 NewWithT(t).Expect(user.Gender).To(Equal(userForSelect.Gender)) 289 }) 290 t.Run("Conflict", func(t *testing.T) { 291 _, err := db.Exec(sqlx.InsertToDB(db, &user, nil)) 292 NewWithT(t).Expect(sqlx.DBErr(err).IsConflict()).To(BeTrue()) 293 }) 294 }) 295 db.(*sqlx.DB).Tables.Range(func(table *builder.Table, idx int) { 296 _, err := db.Exec(db.Dialect().DropTable(table)) 297 NewWithT(t).Expect(err).To(BeNil()) 298 }) 299 }) 300 } 301 */ 302 } 303 304 type UserSet map[string]*User 305 306 func (UserSet) New() interface{} { 307 return &User{} 308 } 309 310 func (u UserSet) Next(v interface{}) error { 311 user := v.(*User) 312 u[user.Name] = user 313 time.Sleep(500 * time.Microsecond) 314 return nil 315 } 316 317 func DISABLED_TestSelect(t *testing.T) { 318 /* 319 dbTest := sqlx.NewDatabase("test_for_select") 320 321 for name, connector := range connectors { 322 t.Run(name, func(t *testing.T) { 323 db := dbTest.OpenDB(connector) 324 table := dbTest.Register(&User{}) 325 326 db.Tables.Range(func(t *builder.Table, idx int) { 327 _, _ = db.Exec(db.Dialect().DropTable(t)) 328 }) 329 330 err := migration.Migrate(db, nil) 331 NewWithT(t).Expect(err).To(BeNil()) 332 333 { 334 columns := table.MustColsByFieldNames("Name", "Gender") 335 values := make([]interface{}, 0) 336 337 for i := 0; i < 1000; i++ { 338 values = append(values, uuid.New().String(), GenderMale) 339 } 340 341 _, err := db.Exec( 342 builder.Insert().Into(table).Values(columns, values...), 343 ) 344 NewWithT(t).Expect(err).To(BeNil()) 345 } 346 347 t.Run("SelectToSlice", func(t *testing.T) { 348 users := make([]User, 0) 349 err := db.QueryAndScan( 350 builder.Select(nil).From( 351 table, 352 builder.Where( 353 table.ColByFieldName("Gender").Eq(GenderMale), 354 ), 355 ), 356 &users, 357 ) 358 NewWithT(t).Expect(err).To(BeNil()) 359 NewWithT(t).Expect(users).To(HaveLen(1000)) 360 }) 361 362 t.Run("SelectToIter", func(t *testing.T) { 363 userSet := UserSet{} 364 err := db.QueryAndScan( 365 builder.Select(nil).From( 366 table, 367 builder.Where( 368 table.ColByFieldName("Gender").Eq(GenderMale), 369 ), 370 ), 371 userSet, 372 ) 373 NewWithT(t).Expect(err).To(BeNil()) 374 NewWithT(t).Expect(userSet).To(HaveLen(1000)) 375 }) 376 377 t.Run("NotFound", func(t *testing.T) { 378 user := User{} 379 err := db.QueryAndScan( 380 builder.Select(nil).From( 381 table, 382 builder.Where( 383 table.ColByFieldName("ID").Eq(1001), 384 ), 385 ), 386 &user, 387 ) 388 NewWithT(t).Expect(sqlx.DBErr(err).IsNotFound()).To(BeTrue()) 389 }) 390 391 t.Run("SelectCount", func(t *testing.T) { 392 count := 0 393 err := db.QueryAndScan( 394 builder.Select(builder.Count()).From(table), 395 &count, 396 ) 397 NewWithT(t).Expect(err).To(BeNil()) 398 NewWithT(t).Expect(count).To(Equal(1000)) 399 }) 400 401 t.Run("Canceled", func(t *testing.T) { 402 ctx, cancel := context.WithCancel(Background()) 403 db2 := db.WithContext(ctx) 404 405 go func() { 406 time.Sleep(3 * time.Millisecond) 407 cancel() 408 }() 409 410 userSet := UserSet{} 411 err := db2.QueryAndScan( 412 builder.Select(nil).From( 413 table, 414 builder.Where( 415 table.ColByFieldName("Gender").Eq(GenderMale), 416 ), 417 ), 418 userSet, 419 ) 420 NewWithT(t).Expect(err).NotTo(BeNil()) 421 }) 422 423 db.Tables.Range(func(tab *builder.Table, idx int) { 424 _, _ = db.Exec(db.Dialect().DropTable(tab)) 425 }) 426 }) 427 } 428 */ 429 }