github.com/gogf/gf@v1.16.9/database/gdb/gdb_z_mysql_internal_test.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gdb 8 9 import ( 10 "fmt" 11 "github.com/gogf/gf/container/gvar" 12 "github.com/gogf/gf/os/gcmd" 13 "github.com/gogf/gf/os/gtime" 14 "github.com/gogf/gf/test/gtest" 15 "testing" 16 ) 17 18 const ( 19 SCHEMA = "test_internal" 20 TestDbUser = "root" 21 TestDbPass = "12345678" 22 ) 23 24 var ( 25 db DB 26 configNode ConfigNode 27 ) 28 29 func init() { 30 parser, err := gcmd.Parse(map[string]bool{ 31 "name": true, 32 "type": true, 33 }, false) 34 gtest.AssertNil(err) 35 configNode = ConfigNode{ 36 Host: "127.0.0.1", 37 Port: "3306", 38 User: TestDbUser, 39 Pass: TestDbPass, 40 Name: parser.GetOpt("name", ""), 41 Type: parser.GetOpt("type", "mysql"), 42 Role: "master", 43 Charset: "utf8", 44 Weight: 1, 45 MaxIdleConnCount: 10, 46 MaxOpenConnCount: 10, 47 MaxConnLifeTime: 600, 48 } 49 AddConfigNode(DefaultGroupName, configNode) 50 // Default db. 51 if r, err := New(); err != nil { 52 gtest.Error(err) 53 } else { 54 db = r 55 } 56 schemaTemplate := "CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET UTF8" 57 if _, err := db.Exec(fmt.Sprintf(schemaTemplate, SCHEMA)); err != nil { 58 gtest.Error(err) 59 } 60 db.SetSchema(SCHEMA) 61 } 62 63 func dropTable(table string) { 64 if _, err := db.Exec(fmt.Sprintf("DROP TABLE IF EXISTS `%s`", table)); err != nil { 65 gtest.Error(err) 66 } 67 } 68 69 func Test_Func_FormatSqlWithArgs(t *testing.T) { 70 // mysql 71 gtest.C(t, func(t *gtest.T) { 72 var s string 73 s = FormatSqlWithArgs("select * from table where id>=? and sex=?", []interface{}{100, 1}) 74 t.Assert(s, "select * from table where id>=100 and sex=1") 75 }) 76 // mssql 77 gtest.C(t, func(t *gtest.T) { 78 var s string 79 s = FormatSqlWithArgs("select * from table where id>=@p1 and sex=@p2", []interface{}{100, 1}) 80 t.Assert(s, "select * from table where id>=100 and sex=1") 81 }) 82 // pgsql 83 gtest.C(t, func(t *gtest.T) { 84 var s string 85 s = FormatSqlWithArgs("select * from table where id>=$1 and sex=$2", []interface{}{100, 1}) 86 t.Assert(s, "select * from table where id>=100 and sex=1") 87 }) 88 // oracle 89 gtest.C(t, func(t *gtest.T) { 90 var s string 91 s = FormatSqlWithArgs("select * from table where id>=:v1 and sex=:v2", []interface{}{100, 1}) 92 t.Assert(s, "select * from table where id>=100 and sex=1") 93 }) 94 } 95 96 func Test_Func_doQuoteWord(t *testing.T) { 97 gtest.C(t, func(t *gtest.T) { 98 array := map[string]string{ 99 "user": "`user`", 100 "user u": "user u", 101 "user_detail": "`user_detail`", 102 "user,user_detail": "user,user_detail", 103 "user u, user_detail ut": "user u, user_detail ut", 104 "u.id asc": "u.id asc", 105 "u.id asc, ut.uid desc": "u.id asc, ut.uid desc", 106 } 107 for k, v := range array { 108 t.Assert(doQuoteWord(k, "`", "`"), v) 109 } 110 }) 111 } 112 113 func Test_Func_doQuoteString(t *testing.T) { 114 gtest.C(t, func(t *gtest.T) { 115 array := map[string]string{ 116 "user": "`user`", 117 "user u": "`user` u", 118 "user,user_detail": "`user`,`user_detail`", 119 "user u, user_detail ut": "`user` u,`user_detail` ut", 120 "u.id, u.name, u.age": "`u`.`id`,`u`.`name`,`u`.`age`", 121 "u.id asc": "`u`.`id` asc", 122 "u.id asc, ut.uid desc": "`u`.`id` asc,`ut`.`uid` desc", 123 "user.user u, user.user_detail ut": "`user`.`user` u,`user`.`user_detail` ut", 124 // mssql global schema access with double dots. 125 "user..user u, user.user_detail ut": "`user`..`user` u,`user`.`user_detail` ut", 126 } 127 for k, v := range array { 128 t.Assert(doQuoteString(k, "`", "`"), v) 129 } 130 }) 131 } 132 133 func Test_Func_addTablePrefix(t *testing.T) { 134 gtest.C(t, func(t *gtest.T) { 135 prefix := "" 136 array := map[string]string{ 137 "user": "`user`", 138 "user u": "`user` u", 139 "user as u": "`user` as u", 140 "user,user_detail": "`user`,`user_detail`", 141 "user u, user_detail ut": "`user` u,`user_detail` ut", 142 "`user`.user_detail": "`user`.`user_detail`", 143 "`user`.`user_detail`": "`user`.`user_detail`", 144 "user as u, user_detail as ut": "`user` as u,`user_detail` as ut", 145 "UserCenter.user as u, UserCenter.user_detail as ut": "`UserCenter`.`user` as u,`UserCenter`.`user_detail` as ut", 146 // mssql global schema access with double dots. 147 "UserCenter..user as u, user_detail as ut": "`UserCenter`..`user` as u,`user_detail` as ut", 148 } 149 for k, v := range array { 150 t.Assert(doHandleTableName(k, prefix, "`", "`"), v) 151 } 152 }) 153 gtest.C(t, func(t *gtest.T) { 154 prefix := "gf_" 155 array := map[string]string{ 156 "user": "`gf_user`", 157 "user u": "`gf_user` u", 158 "user as u": "`gf_user` as u", 159 "user,user_detail": "`gf_user`,`gf_user_detail`", 160 "user u, user_detail ut": "`gf_user` u,`gf_user_detail` ut", 161 "`user`.user_detail": "`user`.`gf_user_detail`", 162 "`user`.`user_detail`": "`user`.`gf_user_detail`", 163 "user as u, user_detail as ut": "`gf_user` as u,`gf_user_detail` as ut", 164 "UserCenter.user as u, UserCenter.user_detail as ut": "`UserCenter`.`gf_user` as u,`UserCenter`.`gf_user_detail` as ut", 165 // mssql global schema access with double dots. 166 "UserCenter..user as u, user_detail as ut": "`UserCenter`..`gf_user` as u,`gf_user_detail` as ut", 167 } 168 for k, v := range array { 169 t.Assert(doHandleTableName(k, prefix, "`", "`"), v) 170 } 171 }) 172 } 173 174 func Test_Model_getSoftFieldName(t *testing.T) { 175 table1 := "soft_deleting_table_" + gtime.TimestampNanoStr() 176 if _, err := db.Exec(fmt.Sprintf(` 177 CREATE TABLE %s ( 178 id int(11) NOT NULL, 179 name varchar(45) DEFAULT NULL, 180 create_at datetime DEFAULT NULL, 181 update_at datetime DEFAULT NULL, 182 delete_at datetime DEFAULT NULL, 183 PRIMARY KEY (id) 184 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 185 `, table1)); err != nil { 186 gtest.Error(err) 187 } 188 defer dropTable(table1) 189 190 table2 := "soft_deleting_table_" + gtime.TimestampNanoStr() 191 if _, err := db.Exec(fmt.Sprintf(` 192 CREATE TABLE %s ( 193 id int(11) NOT NULL, 194 name varchar(45) DEFAULT NULL, 195 createat datetime DEFAULT NULL, 196 updateat datetime DEFAULT NULL, 197 deleteat datetime DEFAULT NULL, 198 PRIMARY KEY (id) 199 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 200 `, table2)); err != nil { 201 gtest.Error(err) 202 } 203 defer dropTable(table2) 204 205 gtest.C(t, func(t *gtest.T) { 206 model := db.Model(table1) 207 gtest.Assert(model.getSoftFieldNameCreated(table2), "createat") 208 gtest.Assert(model.getSoftFieldNameUpdated(table2), "updateat") 209 gtest.Assert(model.getSoftFieldNameDeleted(table2), "deleteat") 210 }) 211 } 212 213 func Test_Model_getConditionForSoftDeleting(t *testing.T) { 214 table1 := "soft_deleting_table_" + gtime.TimestampNanoStr() 215 if _, err := db.Exec(fmt.Sprintf(` 216 CREATE TABLE %s ( 217 id1 int(11) NOT NULL, 218 name1 varchar(45) DEFAULT NULL, 219 create_at datetime DEFAULT NULL, 220 update_at datetime DEFAULT NULL, 221 delete_at datetime DEFAULT NULL, 222 PRIMARY KEY (id1) 223 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 224 `, table1)); err != nil { 225 gtest.Error(err) 226 } 227 defer dropTable(table1) 228 229 table2 := "soft_deleting_table_" + gtime.TimestampNanoStr() 230 if _, err := db.Exec(fmt.Sprintf(` 231 CREATE TABLE %s ( 232 id2 int(11) NOT NULL, 233 name2 varchar(45) DEFAULT NULL, 234 createat datetime DEFAULT NULL, 235 updateat datetime DEFAULT NULL, 236 deleteat datetime DEFAULT NULL, 237 PRIMARY KEY (id2) 238 ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 239 `, table2)); err != nil { 240 gtest.Error(err) 241 } 242 defer dropTable(table2) 243 244 gtest.C(t, func(t *gtest.T) { 245 model := db.Model(table1) 246 t.Assert(model.getConditionForSoftDeleting(), "`delete_at` IS NULL") 247 }) 248 gtest.C(t, func(t *gtest.T) { 249 model := db.Model(fmt.Sprintf(`%s as t`, table1)) 250 t.Assert(model.getConditionForSoftDeleting(), "`delete_at` IS NULL") 251 }) 252 gtest.C(t, func(t *gtest.T) { 253 model := db.Model(fmt.Sprintf(`%s, %s`, table1, table2)) 254 t.Assert(model.getConditionForSoftDeleting(), fmt.Sprintf( 255 "`%s`.`delete_at` IS NULL AND `%s`.`deleteat` IS NULL", 256 table1, table2, 257 )) 258 }) 259 gtest.C(t, func(t *gtest.T) { 260 model := db.Model(fmt.Sprintf(`%s t1, %s as t2`, table1, table2)) 261 t.Assert(model.getConditionForSoftDeleting(), "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL") 262 }) 263 gtest.C(t, func(t *gtest.T) { 264 model := db.Model(fmt.Sprintf(`%s as t1, %s as t2`, table1, table2)) 265 t.Assert(model.getConditionForSoftDeleting(), "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL") 266 }) 267 gtest.C(t, func(t *gtest.T) { 268 model := db.Model(fmt.Sprintf(`%s as t1`, table1)).LeftJoin(table2+" t2", "t2.id2=t1.id1") 269 t.Assert(model.getConditionForSoftDeleting(), "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL") 270 }) 271 gtest.C(t, func(t *gtest.T) { 272 model := db.Model(fmt.Sprintf(`%s`, table1)).LeftJoin(table2, "t2.id2=t1.id1") 273 t.Assert(model.getConditionForSoftDeleting(), fmt.Sprintf( 274 "`%s`.`delete_at` IS NULL AND `%s`.`deleteat` IS NULL", 275 table1, table2, 276 )) 277 }) 278 gtest.C(t, func(t *gtest.T) { 279 model := db.Model(fmt.Sprintf(`%s`, table1)).LeftJoin(table2, "t2.id2=t1.id1").RightJoin(table2, "t2.id2=t1.id1") 280 t.Assert(model.getConditionForSoftDeleting(), fmt.Sprintf( 281 "`%s`.`delete_at` IS NULL AND `%s`.`deleteat` IS NULL AND `%s`.`deleteat` IS NULL", 282 table1, table2, table2, 283 )) 284 }) 285 gtest.C(t, func(t *gtest.T) { 286 model := db.Model(table1+" as t1").LeftJoin(table2+" as t2", "t2.id2=t1.id1").RightJoin(table2+" as t3 ", "t2.id2=t1.id1") 287 t.Assert( 288 model.getConditionForSoftDeleting(), 289 "`t1`.`delete_at` IS NULL AND `t2`.`deleteat` IS NULL AND `t3`.`deleteat` IS NULL", 290 ) 291 }) 292 } 293 294 func Test_isSubQuery(t *testing.T) { 295 gtest.C(t, func(t *gtest.T) { 296 t.Assert(isSubQuery("user"), false) 297 t.Assert(isSubQuery("user.uid"), false) 298 t.Assert(isSubQuery("u, user.uid"), false) 299 t.Assert(isSubQuery("select 1"), true) 300 }) 301 } 302 303 func TestResult_Structs1(t *testing.T) { 304 type A struct { 305 Id int `orm:"id"` 306 } 307 type B struct { 308 *A 309 Name string 310 } 311 gtest.C(t, func(t *gtest.T) { 312 r := Result{ 313 Record{"id": gvar.New(nil), "name": gvar.New("john")}, 314 Record{"id": gvar.New(nil), "name": gvar.New("smith")}, 315 } 316 array := make([]*B, 2) 317 err := r.Structs(&array) 318 t.AssertNil(err) 319 t.Assert(array[0].Id, 0) 320 t.Assert(array[1].Id, 0) 321 t.Assert(array[0].Name, "john") 322 t.Assert(array[1].Name, "smith") 323 }) 324 } 325 326 // https://github.com/gogf/gf/issues/1159 327 func Test_ScanList_NoRecreate_PtrAttribute(t *testing.T) { 328 gtest.C(t, func(t *gtest.T) { 329 type S1 struct { 330 Id int 331 Name string 332 Age int 333 Score int 334 } 335 type S3 struct { 336 One *S1 337 } 338 var ( 339 s []*S3 340 err error 341 ) 342 r1 := Result{ 343 Record{ 344 "id": gvar.New(1), 345 "name": gvar.New("john"), 346 "age": gvar.New(16), 347 }, 348 Record{ 349 "id": gvar.New(2), 350 "name": gvar.New("smith"), 351 "age": gvar.New(18), 352 }, 353 } 354 err = r1.ScanList(&s, "One") 355 t.AssertNil(err) 356 t.Assert(len(s), 2) 357 t.Assert(s[0].One.Name, "john") 358 t.Assert(s[0].One.Age, 16) 359 t.Assert(s[1].One.Name, "smith") 360 t.Assert(s[1].One.Age, 18) 361 362 r2 := Result{ 363 Record{ 364 "id": gvar.New(1), 365 "age": gvar.New(20), 366 }, 367 Record{ 368 "id": gvar.New(2), 369 "age": gvar.New(21), 370 }, 371 } 372 err = r2.ScanList(&s, "One", "One", "id:Id") 373 t.AssertNil(err) 374 t.Assert(len(s), 2) 375 t.Assert(s[0].One.Name, "john") 376 t.Assert(s[0].One.Age, 20) 377 t.Assert(s[1].One.Name, "smith") 378 t.Assert(s[1].One.Age, 21) 379 }) 380 } 381 382 // https://github.com/gogf/gf/issues/1159 383 func Test_ScanList_NoRecreate_StructAttribute(t *testing.T) { 384 gtest.C(t, func(t *gtest.T) { 385 type S1 struct { 386 Id int 387 Name string 388 Age int 389 Score int 390 } 391 type S3 struct { 392 One S1 393 } 394 var ( 395 s []*S3 396 err error 397 ) 398 r1 := Result{ 399 Record{ 400 "id": gvar.New(1), 401 "name": gvar.New("john"), 402 "age": gvar.New(16), 403 }, 404 Record{ 405 "id": gvar.New(2), 406 "name": gvar.New("smith"), 407 "age": gvar.New(18), 408 }, 409 } 410 err = r1.ScanList(&s, "One") 411 t.AssertNil(err) 412 t.Assert(len(s), 2) 413 t.Assert(s[0].One.Name, "john") 414 t.Assert(s[0].One.Age, 16) 415 t.Assert(s[1].One.Name, "smith") 416 t.Assert(s[1].One.Age, 18) 417 418 r2 := Result{ 419 Record{ 420 "id": gvar.New(1), 421 "age": gvar.New(20), 422 }, 423 Record{ 424 "id": gvar.New(2), 425 "age": gvar.New(21), 426 }, 427 } 428 err = r2.ScanList(&s, "One", "One", "id:Id") 429 t.AssertNil(err) 430 t.Assert(len(s), 2) 431 t.Assert(s[0].One.Name, "john") 432 t.Assert(s[0].One.Age, 20) 433 t.Assert(s[1].One.Name, "smith") 434 t.Assert(s[1].One.Age, 21) 435 }) 436 } 437 438 // https://github.com/gogf/gf/issues/1159 439 func Test_ScanList_NoRecreate_SliceAttribute_Ptr(t *testing.T) { 440 gtest.C(t, func(t *gtest.T) { 441 type S1 struct { 442 Id int 443 Name string 444 Age int 445 Score int 446 } 447 type S2 struct { 448 Id int 449 Pid int 450 Name string 451 Age int 452 Score int 453 } 454 type S3 struct { 455 One *S1 456 Many []*S2 457 } 458 var ( 459 s []*S3 460 err error 461 ) 462 r1 := Result{ 463 Record{ 464 "id": gvar.New(1), 465 "name": gvar.New("john"), 466 "age": gvar.New(16), 467 }, 468 Record{ 469 "id": gvar.New(2), 470 "name": gvar.New("smith"), 471 "age": gvar.New(18), 472 }, 473 } 474 err = r1.ScanList(&s, "One") 475 t.AssertNil(err) 476 t.Assert(len(s), 2) 477 t.Assert(s[0].One.Name, "john") 478 t.Assert(s[0].One.Age, 16) 479 t.Assert(s[1].One.Name, "smith") 480 t.Assert(s[1].One.Age, 18) 481 482 r2 := Result{ 483 Record{ 484 "id": gvar.New(100), 485 "pid": gvar.New(1), 486 "age": gvar.New(30), 487 "name": gvar.New("john"), 488 }, 489 Record{ 490 "id": gvar.New(200), 491 "pid": gvar.New(1), 492 "age": gvar.New(31), 493 "name": gvar.New("smith"), 494 }, 495 } 496 err = r2.ScanList(&s, "Many", "One", "pid:Id") 497 //fmt.Printf("%+v", err) 498 t.AssertNil(err) 499 t.Assert(len(s), 2) 500 t.Assert(s[0].One.Name, "john") 501 t.Assert(s[0].One.Age, 16) 502 t.Assert(len(s[0].Many), 2) 503 t.Assert(s[0].Many[0].Name, "john") 504 t.Assert(s[0].Many[0].Age, 30) 505 t.Assert(s[0].Many[1].Name, "smith") 506 t.Assert(s[0].Many[1].Age, 31) 507 508 t.Assert(s[1].One.Name, "smith") 509 t.Assert(s[1].One.Age, 18) 510 t.Assert(len(s[1].Many), 0) 511 512 r3 := Result{ 513 Record{ 514 "id": gvar.New(100), 515 "pid": gvar.New(1), 516 "age": gvar.New(40), 517 }, 518 Record{ 519 "id": gvar.New(200), 520 "pid": gvar.New(1), 521 "age": gvar.New(41), 522 }, 523 } 524 err = r3.ScanList(&s, "Many", "One", "pid:Id") 525 //fmt.Printf("%+v", err) 526 t.AssertNil(err) 527 t.Assert(len(s), 2) 528 t.Assert(s[0].One.Name, "john") 529 t.Assert(s[0].One.Age, 16) 530 t.Assert(len(s[0].Many), 2) 531 t.Assert(s[0].Many[0].Name, "john") 532 t.Assert(s[0].Many[0].Age, 40) 533 t.Assert(s[0].Many[1].Name, "smith") 534 t.Assert(s[0].Many[1].Age, 41) 535 536 t.Assert(s[1].One.Name, "smith") 537 t.Assert(s[1].One.Age, 18) 538 t.Assert(len(s[1].Many), 0) 539 }) 540 } 541 542 // https://github.com/gogf/gf/issues/1159 543 func Test_ScanList_NoRecreate_SliceAttribute_Struct(t *testing.T) { 544 gtest.C(t, func(t *gtest.T) { 545 type S1 struct { 546 Id int 547 Name string 548 Age int 549 Score int 550 } 551 type S2 struct { 552 Id int 553 Pid int 554 Name string 555 Age int 556 Score int 557 } 558 type S3 struct { 559 One S1 560 Many []S2 561 } 562 var ( 563 s []S3 564 err error 565 ) 566 r1 := Result{ 567 Record{ 568 "id": gvar.New(1), 569 "name": gvar.New("john"), 570 "age": gvar.New(16), 571 }, 572 Record{ 573 "id": gvar.New(2), 574 "name": gvar.New("smith"), 575 "age": gvar.New(18), 576 }, 577 } 578 err = r1.ScanList(&s, "One") 579 t.AssertNil(err) 580 t.Assert(len(s), 2) 581 t.Assert(s[0].One.Name, "john") 582 t.Assert(s[0].One.Age, 16) 583 t.Assert(s[1].One.Name, "smith") 584 t.Assert(s[1].One.Age, 18) 585 586 r2 := Result{ 587 Record{ 588 "id": gvar.New(100), 589 "pid": gvar.New(1), 590 "age": gvar.New(30), 591 "name": gvar.New("john"), 592 }, 593 Record{ 594 "id": gvar.New(200), 595 "pid": gvar.New(1), 596 "age": gvar.New(31), 597 "name": gvar.New("smith"), 598 }, 599 } 600 err = r2.ScanList(&s, "Many", "One", "pid:Id") 601 //fmt.Printf("%+v", err) 602 t.AssertNil(err) 603 t.Assert(len(s), 2) 604 t.Assert(s[0].One.Name, "john") 605 t.Assert(s[0].One.Age, 16) 606 t.Assert(len(s[0].Many), 2) 607 t.Assert(s[0].Many[0].Name, "john") 608 t.Assert(s[0].Many[0].Age, 30) 609 t.Assert(s[0].Many[1].Name, "smith") 610 t.Assert(s[0].Many[1].Age, 31) 611 612 t.Assert(s[1].One.Name, "smith") 613 t.Assert(s[1].One.Age, 18) 614 t.Assert(len(s[1].Many), 0) 615 616 r3 := Result{ 617 Record{ 618 "id": gvar.New(100), 619 "pid": gvar.New(1), 620 "age": gvar.New(40), 621 }, 622 Record{ 623 "id": gvar.New(200), 624 "pid": gvar.New(1), 625 "age": gvar.New(41), 626 }, 627 } 628 err = r3.ScanList(&s, "Many", "One", "pid:Id") 629 //fmt.Printf("%+v", err) 630 t.AssertNil(err) 631 t.Assert(len(s), 2) 632 t.Assert(s[0].One.Name, "john") 633 t.Assert(s[0].One.Age, 16) 634 t.Assert(len(s[0].Many), 2) 635 t.Assert(s[0].Many[0].Name, "john") 636 t.Assert(s[0].Many[0].Age, 40) 637 t.Assert(s[0].Many[1].Name, "smith") 638 t.Assert(s[0].Many[1].Age, 41) 639 640 t.Assert(s[1].One.Name, "smith") 641 t.Assert(s[1].One.Age, 18) 642 t.Assert(len(s[1].Many), 0) 643 }) 644 }