github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/field/export_test.go (about) 1 package field_test 2 3 import ( 4 "database/sql/driver" 5 "fmt" 6 "strings" 7 "testing" 8 "time" 9 10 "github.com/unionj-cloud/go-doudou/v2/toolkit/gormgen/field" 11 ) 12 13 var _ field.ScanValuer = new(password) 14 15 type password string 16 17 func (p *password) Scan(src interface{}) error { 18 *p = password(fmt.Sprintf("this is password {%q}", src)) 19 return nil 20 } 21 func (p password) Value() (driver.Value, error) { 22 return strings.TrimPrefix(strings.TrimSuffix(string(p), "}"), "this is password {"), nil 23 } 24 25 func TestExpr_Build(t *testing.T) { 26 timeData, _ := time.Parse("2006-01-02 15:04:05", "2021-06-29 15:11:49") 27 const p = password("i am password") 28 29 testcases := []struct { 30 Expr field.Expr 31 ExpectedVars []interface{} 32 Result string 33 }{ 34 // ======================== generic ======================== 35 { 36 Expr: field.NewField("user", "password").Eq(p), 37 ExpectedVars: []interface{}{p}, 38 Result: "`user`.`password` = ?", 39 }, 40 { 41 Expr: field.NewField("", "id").EqCol(field.NewField("", "new_id")), 42 Result: "`id` = `new_id`", 43 }, 44 { 45 Expr: field.NewField("", "id").NeqCol(field.NewField("", "new_id")), 46 Result: "`id` <> `new_id`", 47 }, 48 { 49 Expr: field.NewField("", "id").LtCol(field.NewField("", "new_id")), 50 Result: "`id` < `new_id`", 51 }, 52 { 53 Expr: field.NewField("", "id").LteCol(field.NewField("", "new_id")), 54 Result: "`id` <= `new_id`", 55 }, 56 { 57 Expr: field.NewField("", "id").GtCol(field.NewField("", "new_id")), 58 Result: "`id` > `new_id`", 59 }, 60 { 61 Expr: field.NewField("", "id").GteCol(field.NewField("", "new_id")), 62 Result: "`id` >= `new_id`", 63 }, 64 { 65 Expr: field.NewField("", "id").EqCol(field.NewField("", "new_id").Avg()), 66 Result: "`id` = AVG(`new_id`)", 67 }, 68 { 69 Expr: field.NewField("", "id").EqCol(field.NewField("", "new_id").WithTable("tableB")), 70 Result: "`id` = `tableB`.`new_id`", 71 }, 72 { 73 Expr: field.NewField("", "id").EqCol(field.NewField("", "new_id").WithTable("tableB")), 74 Result: "`id` = `tableB`.`new_id`", 75 }, 76 { 77 Expr: field.NewField("", "id").NeqCol(field.NewField("", "new_id").WithTable("tableB")), 78 Result: "`id` <> `tableB`.`new_id`", 79 }, 80 { 81 Expr: field.NewField("", "id").IsNull(), 82 Result: "`id` IS NULL", 83 }, 84 { 85 Expr: field.NewField("", "id").IsNotNull(), 86 Result: "`id` IS NOT NULL", 87 }, 88 { 89 Expr: field.NewField("", "id").GroupConcat(), 90 Result: "GROUP_CONCAT(`id`)", 91 }, 92 { 93 Expr: field.Func.UnixTimestamp(), 94 Result: "UNIX_TIMESTAMP()", 95 }, 96 { 97 Expr: field.Func.UnixTimestamp("2005-03-27 03:00:00").Mul(99), 98 Result: "(UNIX_TIMESTAMP(?))*?", 99 ExpectedVars: []interface{}{"2005-03-27 03:00:00", uint64(99)}, 100 }, 101 { 102 Expr: field.NewInt("t1", "id").AddCol(field.NewInt("t2", "num")), 103 Result: "`t1`.`id` + `t2`.`num`", 104 }, 105 { 106 Expr: field.NewInt("t1", "id").AddCol(field.NewInt("t1", "num")).SubCol(field.NewInt("t1", "age")), 107 Result: "`t1`.`id` + `t1`.`num` - `t1`.`age`", 108 }, 109 { 110 Expr: field.NewInt("t1", "id").AddCol(field.NewInt("t1", "num")).SubCol(field.NewInt("t1", "age")).MulCol(field.NewInt("t1", "age")).DivCol(field.NewInt("t1", "base")), 111 Result: "((`t1`.`id` + `t1`.`num` - `t1`.`age`) * (`t1`.`age`)) / (`t1`.`base`)", 112 }, 113 { 114 Expr: field.NewInt("t1", "id").AddCol(field.NewInt("t2", "num").Add(1)), 115 Result: "`t1`.`id` + `t2`.`num`+?", 116 ExpectedVars: []interface{}{int(1)}, 117 }, 118 { 119 Expr: field.NewInt("t1", "id").EqCol(field.NewInt("t1", "id").AddCol(field.NewInt("t2", "num").Add(1))), 120 Result: "`t1`.`id` = `t1`.`id` + `t2`.`num`+?", 121 ExpectedVars: []interface{}{int(1)}, 122 }, 123 { 124 Expr: field.NewInt("t1", "a").AddCol(field.NewInt("t2", "b").Add(1)).(field.Field).GtCol(field.NewInt("t", "c")), 125 Result: "`t1`.`a` + `t2`.`b`+? > `t`.`c`", 126 ExpectedVars: []interface{}{int(1)}, 127 }, 128 { 129 Expr: field.ALL.Count(), 130 Result: "COUNT(*)", 131 }, 132 { 133 Expr: field.ALL.Distinct().Count(), 134 Result: "COUNT(DISTINCT *)", 135 }, 136 { 137 Expr: field.NewAsterisk("user").Count(), 138 Result: "COUNT(`user`.*)", 139 }, 140 { 141 Expr: field.NewAsterisk("user").Distinct().Count(), 142 Result: "COUNT(DISTINCT `user`.*)", 143 }, 144 // ======================== integer ======================== 145 { 146 Expr: field.NewUint("", "id"), 147 Result: "`id`", 148 }, 149 { 150 Expr: field.NewUint("user", "id").Sum().Gt(100), 151 ExpectedVars: []interface{}{uint(100)}, 152 Result: "SUM(`user`.`id`) > ?", 153 }, 154 { 155 Expr: field.NewUint("", "i`d"), 156 Result: "`i``d`", 157 }, 158 { 159 Expr: field.NewUint("", "id").Avg(), 160 Result: "AVG(`id`)", 161 }, 162 { 163 Expr: field.NewUint("", "id").Desc(), 164 Result: "`id` DESC", 165 }, 166 { 167 Expr: field.NewUint("", "id").As("number"), 168 Result: "`id` AS `number`", 169 }, 170 { 171 Expr: field.NewUint("", "id").Avg().As("number"), 172 Result: "AVG(`id`) AS `number`", 173 }, 174 { 175 Expr: field.NewUint("", "id").Eq(10), 176 ExpectedVars: []interface{}{uint(10)}, 177 Result: "`id` = ?", 178 }, 179 { 180 Expr: field.NewUint("", "id").Neq(10), 181 ExpectedVars: []interface{}{uint(10)}, 182 Result: "`id` <> ?", 183 }, 184 { 185 Expr: field.NewUint("", "id").Gt(1), 186 ExpectedVars: []interface{}{uint(1)}, 187 Result: "`id` > ?", 188 }, 189 { 190 Expr: field.NewUint("", "id").Gte(1), 191 ExpectedVars: []interface{}{uint(1)}, 192 Result: "`id` >= ?", 193 }, 194 { 195 Expr: field.NewUint("", "id").Lt(1), 196 ExpectedVars: []interface{}{uint(1)}, 197 Result: "`id` < ?", 198 }, 199 { 200 Expr: field.NewUint("", "id").Lte(1), 201 ExpectedVars: []interface{}{uint(1)}, 202 Result: "`id` <= ?", 203 }, 204 { 205 Expr: field.NewUint("", "id").Mod(7), 206 ExpectedVars: []interface{}{uint(7)}, 207 Result: "`id`%?", 208 }, 209 { 210 Expr: field.And(field.NewUint("", "id").Gt(1), field.NewUint("", "id").Lt(10)), 211 ExpectedVars: []interface{}{uint(1), uint(10)}, 212 Result: "(`id` > ? AND `id` < ?)", 213 }, 214 { 215 Expr: field.Or(field.NewUint("", "id").Lt(4), field.NewUint("", "id").Gt(6)), 216 ExpectedVars: []interface{}{uint(4), uint(6)}, 217 Result: "(`id` < ? OR `id` > ?)", 218 }, 219 { 220 Expr: field.NewUint("", "id").In(1, 2, 3), 221 ExpectedVars: []interface{}{uint(1), uint(2), uint(3)}, 222 Result: "`id` IN (?,?,?)", 223 }, 224 { 225 Expr: field.NewUint("", "id").NotIn(1, 2, 3), 226 ExpectedVars: []interface{}{uint(1), uint(2), uint(3)}, 227 Result: "`id` NOT IN (?,?,?)", 228 }, 229 { 230 Expr: field.NewUint("", "id").Between(1, 10), 231 ExpectedVars: []interface{}{uint(1), uint(10)}, 232 Result: "`id` BETWEEN ? AND ?", 233 }, 234 { 235 Expr: field.NewUint("", "id").Count(), 236 Result: "COUNT(`id`)", 237 }, 238 { 239 Expr: field.NewUint("", "id").Count().As("UserID"), 240 Result: "COUNT(`id`) AS `UserID`", 241 }, 242 { 243 Expr: field.NewUint("", "id").Distinct(), 244 Result: "DISTINCT `id`", 245 }, 246 { 247 Expr: field.NewUint("", "id").Distinct().Count(), 248 Result: "COUNT(DISTINCT `id`)", 249 }, 250 { 251 Expr: field.NewUint("", "id").Distinct().Count().As("UserID"), 252 Result: "COUNT(DISTINCT `id`) AS `UserID`", 253 }, 254 { 255 Expr: field.NewInt("", "age").RightShift(3), 256 ExpectedVars: []interface{}{3}, 257 Result: "`age`>>?", 258 }, 259 { 260 Expr: field.NewInt("", "age").LeftShift(3), 261 ExpectedVars: []interface{}{3}, 262 Result: "`age`<<?", 263 }, 264 { 265 Expr: field.NewInt("", "age").Add(1).Mul(2).Div(3), 266 ExpectedVars: []interface{}{1, 2, 3}, 267 Result: "((`age`+?)*?)/?", 268 }, 269 // ======================== float ======================== 270 { 271 Expr: field.NewFloat64("", "score").Add(3.0), 272 ExpectedVars: []interface{}{float64(3.0)}, 273 Result: "`score`+?", 274 }, 275 { 276 Expr: field.NewFloat64("", "score").Sub(3.0), 277 ExpectedVars: []interface{}{float64(3.0)}, 278 Result: "`score`-?", 279 }, 280 { 281 Expr: field.NewFloat64("", "score").Mul(3.0), 282 ExpectedVars: []interface{}{float64(3.0)}, 283 Result: "`score`*?", 284 }, 285 { 286 Expr: field.NewFloat64("", "score").Div(3.0), 287 ExpectedVars: []interface{}{float64(3.0)}, 288 Result: "`score`/?", 289 }, 290 { 291 Expr: field.NewFloat64("", "score").FloorDiv(3.0), 292 ExpectedVars: []interface{}{float64(3.0)}, 293 Result: "`score` DIV ?", 294 }, 295 // ======================== string ======================== 296 { 297 Expr: field.NewString("", "name").Eq("tom"), 298 ExpectedVars: []interface{}{"tom"}, 299 Result: "`name` = ?", 300 }, 301 { 302 Expr: field.NewString("", "name").Neq("tom"), 303 ExpectedVars: []interface{}{"tom"}, 304 Result: "`name` <> ?", 305 }, 306 { 307 Expr: field.NewString("", "name").Like("%%tom%%"), 308 ExpectedVars: []interface{}{"%%tom%%"}, 309 Result: "`name` LIKE ?", 310 }, 311 { 312 Expr: field.NewString("", "name").NotLike("%%tom%%"), 313 ExpectedVars: []interface{}{"%%tom%%"}, 314 Result: "`name` NOT LIKE ?", 315 }, 316 { 317 Expr: field.NewString("", "name").Regexp(".*"), 318 ExpectedVars: []interface{}{".*"}, 319 Result: "`name` REGEXP ?", 320 }, 321 { 322 Expr: field.NewString("", "name").NotRegxp(".*"), 323 ExpectedVars: []interface{}{".*"}, 324 Result: "NOT `name` REGEXP ?", 325 }, 326 { 327 Expr: field.NewString("", "address").FindInSetWith("sh"), 328 ExpectedVars: []interface{}{"sh"}, 329 Result: "FIND_IN_SET(?,`address`)", 330 }, 331 { 332 Expr: field.NewString("", "address").FindInSet("sh"), 333 ExpectedVars: []interface{}{"sh"}, 334 Result: "FIND_IN_SET(`address`,?)", 335 }, 336 { 337 Expr: field.NewString("", "address").Replace("address", "path"), 338 ExpectedVars: []interface{}{"address", "path"}, 339 Result: "REPLACE(`address`,?,?)", 340 }, 341 { 342 Expr: field.NewString("", "address").Concat("[", "]"), 343 ExpectedVars: []interface{}{"[", "]"}, 344 Result: "CONCAT(?,`address`,?)", 345 }, 346 { 347 Expr: field.NewString("", "address").Concat("", "_"), 348 ExpectedVars: []interface{}{"_"}, 349 Result: "CONCAT(`address`,?)", 350 }, 351 { 352 Expr: field.NewString("", "address").Replace("address", "path").Concat("[", "]"), 353 ExpectedVars: []interface{}{"[", "address", "path", "]"}, 354 Result: "CONCAT(?,REPLACE(`address`,?,?),?)", 355 }, 356 // ======================== time ======================== 357 { 358 Expr: field.NewTime("", "creatAt").Eq(timeData), 359 ExpectedVars: []interface{}{timeData}, 360 Result: "`creatAt` = ?", 361 }, 362 { 363 Expr: field.NewTime("", "creatAt").Gt(timeData), 364 ExpectedVars: []interface{}{timeData}, 365 Result: "`creatAt` > ?", 366 }, 367 { 368 Expr: field.NewTime("", "creatAt").Gte(timeData), 369 ExpectedVars: []interface{}{timeData}, 370 Result: "`creatAt` >= ?", 371 }, 372 { 373 Expr: field.NewTime("", "creatAt").Lt(timeData), 374 ExpectedVars: []interface{}{timeData}, 375 Result: "`creatAt` < ?", 376 }, 377 { 378 Expr: field.NewTime("", "creatAt").Lte(timeData), 379 ExpectedVars: []interface{}{timeData}, 380 Result: "`creatAt` <= ?", 381 }, 382 { 383 Expr: field.NewTime("", "creatAt").Between(timeData, timeData.Add(24*time.Hour)), 384 ExpectedVars: []interface{}{timeData, timeData.Add(24 * time.Hour)}, 385 Result: "`creatAt` BETWEEN ? AND ?", 386 }, 387 { 388 Expr: field.NewTime("", "creatAt").Add(24 * time.Hour), 389 ExpectedVars: []interface{}{time.Duration(24 * time.Hour).Microseconds()}, 390 Result: "DATE_ADD(`creatAt`, INTERVAL ? MICROSECOND)", 391 }, 392 { 393 Expr: field.NewTime("", "creatAt").Sub(24 * time.Hour), 394 ExpectedVars: []interface{}{time.Duration(24 * time.Hour).Microseconds()}, 395 Result: "DATE_SUB(`creatAt`, INTERVAL ? MICROSECOND)", 396 }, 397 { 398 Expr: field.NewTime("", "updateAt").DateFormat("%W %M %Y"), 399 ExpectedVars: []interface{}{"%W %M %Y"}, 400 Result: "DATE_FORMAT(`updateAt`,?)", 401 }, 402 // ======================== bool ======================== 403 { 404 Expr: field.NewBool("", "male").Not(), 405 Result: "NOT `male`", 406 }, 407 { 408 Expr: field.NewBool("", "male").Is(true), 409 ExpectedVars: []interface{}{true}, 410 Result: "`male` = ?", 411 }, 412 { 413 Expr: field.NewBool("", "male").And(true), 414 ExpectedVars: []interface{}{true}, 415 Result: "`male` AND ?", 416 }, 417 { 418 Expr: field.NewBool("", "male").Or(true), 419 ExpectedVars: []interface{}{true}, 420 Result: "`male` OR ?", 421 }, 422 } 423 424 for _, testcase := range testcases { 425 field.CheckBuildExpr(t, testcase.Expr, testcase.Result, testcase.ExpectedVars) 426 } 427 } 428 429 func TestExpr_BuildColumn(t *testing.T) { 430 stmt := field.GetStatement() 431 id := field.NewUint("user", "id") 432 expectColumnStr := "`id`" 433 expectColumnStrWithTable := "`user`.`id`" 434 expectColumnStrWithoutQuote := "id" 435 expectColumnStrWithTableWithoutQuote := "user.id" 436 437 if colStr := id.BuildColumn(stmt).String(); colStr != expectColumnStr { 438 t.Errorf("id.BuildColumn(stmt).String() got: %q, except: %q", colStr, expectColumnStr) 439 } 440 if colStr := id.BuildColumn(stmt, field.WithTable).String(); colStr != expectColumnStrWithTable { 441 t.Errorf("id.BuildColumn(stmt, field.WithTable).String() got: %q, except: %q", colStr, expectColumnStrWithTable) 442 } 443 if colStr := id.BuildColumn(stmt, field.WithoutQuote).String(); colStr != expectColumnStrWithoutQuote { 444 t.Errorf("id.BuildColumn(stmt, field.WithoutQuote).String() got: %q, except: %q", colStr, expectColumnStrWithoutQuote) 445 } 446 if colStr := id.BuildColumn(stmt, field.WithTable, field.WithoutQuote).String(); colStr != expectColumnStrWithTableWithoutQuote { 447 t.Errorf("id.BuildColumn(stmt, field.WithTable, field.WithoutQuote).String() got: %q, except: %q", colStr, expectColumnStrWithTableWithoutQuote) 448 } 449 450 expectStarColumnStr := "*" 451 if colStr := field.Star.BuildColumn(stmt).String(); colStr != expectStarColumnStr { 452 t.Errorf("field.Star.BuildColumn(stmt).String() got: %q, except: %q", colStr, expectStarColumnStr) 453 } 454 455 allField := field.NewString("user", "*") 456 expectStarColumnStrWithTable := "`user`.*" 457 if colStr := allField.BuildColumn(stmt, field.WithTable).String(); colStr != expectStarColumnStrWithTable { 458 t.Errorf("allField.BuildColumn(stmt, field.WithTable).String() got: %q, except: %q", colStr, expectStarColumnStrWithTable) 459 } 460 } 461 462 func BenchmarkExpr_Count(b *testing.B) { 463 id := field.NewUint("", "id") 464 for i := 0; i < b.N; i++ { 465 n := id.Count() 466 _ = n 467 } 468 } 469 470 func TestRelation_StructField(t *testing.T) { 471 var testdatas = []struct { 472 relation *field.Relation 473 expectedValue string 474 }{ 475 { 476 relation: field.NewRelation( 477 "CreditCards", "model.CreditCard", 478 *field.NewRelation("Owner", "model.Owner"), 479 *field.NewRelation("Bank", "model.Bank", 480 *field.NewRelation("Manager", "model.Bank"), 481 *field.NewRelation("City", "model.City", 482 *field.NewRelation("State", "model.Bank"), 483 ), 484 ), 485 ), 486 expectedValue: "Owner struct {\nfield.RelationField\n}\nBank struct {\nfield.RelationField\nManager struct {\nfield.RelationField\n}\nCity struct {\nfield.RelationField\nState struct {\nfield.RelationField\n}\n}\n}\n", 487 }, 488 } 489 490 for _, testdata := range testdatas { 491 if result := testdata.relation.StructField(); result != testdata.expectedValue { 492 t.Errorf("StructField fail: except %q, got %q", testdata.expectedValue, result) 493 } 494 } 495 } 496 497 func TestRelation_StructFieldInit(t *testing.T) { 498 var testdatas = []struct { 499 relation *field.Relation 500 expectedValue string 501 }{ 502 { 503 relation: field.NewRelation( 504 "CreditCards", "model.CreditCard", 505 *field.NewRelation("Owner", "model.Owner"), 506 *field.NewRelation("Bank", "model.Bank", 507 *field.NewRelation("Manager", "model.Manager"), 508 *field.NewRelation("City", "model.City", 509 *field.NewRelation("State", "model.State"), 510 ), 511 ), 512 ), 513 expectedValue: "RelationField: field.NewRelation(\"CreditCards\", \"model.CreditCard\"),\nOwner: struct {\nfield.RelationField\n}{\nRelationField: field.NewRelation(\"CreditCards.Owner\", \"model.Owner\"),\n},\nBank: struct {\nfield.RelationField\nManager struct {\nfield.RelationField\n}\nCity struct {\nfield.RelationField\nState struct {\nfield.RelationField\n}\n}}{\nRelationField: field.NewRelation(\"CreditCards.Bank\", \"model.Bank\"),\nManager: struct {\nfield.RelationField\n}{\nRelationField: field.NewRelation(\"CreditCards.Bank.Manager\", \"model.Manager\"),\n},\nCity: struct {\nfield.RelationField\nState struct {\nfield.RelationField\n}}{\nRelationField: field.NewRelation(\"CreditCards.Bank.City\", \"model.City\"),\nState: struct {\nfield.RelationField\n}{\nRelationField: field.NewRelation(\"CreditCards.Bank.City.State\", \"model.State\"),\n},\n},\n},\n", 514 }, 515 } 516 517 for _, testdata := range testdatas { 518 if result := testdata.relation.StructFieldInit(); result != testdata.expectedValue { 519 t.Errorf("StructField fail: except %q, got %q", testdata.expectedValue, result) 520 } 521 } 522 } 523 524 func expectedStruct() { // nolint 525 _ = struct { 526 field.RelationField 527 Owner struct { 528 field.RelationField 529 } 530 Bank struct { 531 field.RelationField 532 Manager struct { 533 field.RelationField 534 } 535 City struct { 536 field.RelationField 537 State struct { 538 field.RelationField 539 } 540 } 541 } 542 }{ 543 RelationField: field.NewRelation("CreditCards", "model.CreditCard"), 544 Owner: struct { 545 field.RelationField 546 }{ 547 RelationField: field.NewRelation("CreditCards.Owner", "model.Owner"), 548 }, 549 Bank: struct { 550 field.RelationField 551 Manager struct { 552 field.RelationField 553 } 554 City struct { 555 field.RelationField 556 State struct { 557 field.RelationField 558 } 559 } 560 }{ 561 RelationField: field.NewRelation("CreditCards.Bank", "model.Bank"), 562 Manager: struct { 563 field.RelationField 564 }{ 565 RelationField: field.NewRelation("CreditCards.Bank.Manager", "model.Manager"), 566 }, 567 City: struct { 568 field.RelationField 569 State struct { 570 field.RelationField 571 } 572 }{ 573 RelationField: field.NewRelation("CreditCards.Bank.City", "model.City"), 574 State: struct { 575 field.RelationField 576 }{ 577 RelationField: field.NewRelation("CreditCards.Bank.City.State", "model.State"), 578 }, 579 }, 580 }, 581 } 582 }