github.com/yongjacky/phoenix-go-orm-builder@v0.3.5/builder_test.go (about) 1 // Copyright 2016 The Xorm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package builder 6 7 import ( 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 type MyInt int 14 15 func TestBuilderCond(t *testing.T) { 16 var cases = []struct { 17 cond Cond 18 sql string 19 args []interface{} 20 }{ 21 { 22 Eq{"a": 1}.And(Like{"b", "c"}).Or(Eq{"a": 2}.And(Like{"b", "g"})), 23 "(a=? AND b LIKE ?) OR (a=? AND b LIKE ?)", 24 []interface{}{1, "%c%", 2, "%g%"}, 25 }, 26 { 27 Eq{"a": 1}.Or(Like{"b", "c"}).And(Eq{"a": 2}.Or(Like{"b", "g"})), 28 "(a=? OR b LIKE ?) AND (a=? OR b LIKE ?)", 29 []interface{}{1, "%c%", 2, "%g%"}, 30 }, 31 { 32 Eq{"d": []string{"e", "f"}}, 33 "d IN (?,?)", 34 []interface{}{"e", "f"}, 35 }, 36 { 37 Eq{"e": Select("id").From("f").Where(Eq{"g": 1})}, 38 "e=(SELECT id FROM f WHERE g=?)", 39 []interface{}{1}, 40 }, 41 { 42 Eq{"e": Expr("SELECT id FROM f WHERE g=?", 1)}, 43 "e=(SELECT id FROM f WHERE g=?)", 44 []interface{}{1}, 45 }, 46 { 47 Like{"a", "%1"}.And(Like{"b", "%2"}), 48 "a LIKE ? AND b LIKE ?", 49 []interface{}{"%1", "%2"}, 50 }, 51 { 52 Like{"a", "%1"}.Or(Like{"b", "%2"}), 53 "a LIKE ? OR b LIKE ?", 54 []interface{}{"%1", "%2"}, 55 }, 56 { 57 Neq{"d": "e"}.Or(Neq{"f": "g"}), 58 "d<>? OR f<>?", 59 []interface{}{"e", "g"}, 60 }, 61 { 62 Neq{"d": []string{"e", "f"}}, 63 "d NOT IN (?,?)", 64 []interface{}{"e", "f"}, 65 }, 66 { 67 Neq{"e": Select("id").From("f").Where(Eq{"g": 1})}, 68 "e<>(SELECT id FROM f WHERE g=?)", 69 []interface{}{1}, 70 }, 71 { 72 Neq{"e": Expr("SELECT id FROM f WHERE g=?", 1)}, 73 "e<>(SELECT id FROM f WHERE g=?)", 74 []interface{}{1}, 75 }, 76 { 77 Lt{"d": 3}, 78 "d<?", 79 []interface{}{3}, 80 }, 81 { 82 Lt{"d": 3}.And(Lt{"e": 4}), 83 "d<? AND e<?", 84 []interface{}{3, 4}, 85 }, 86 { 87 Lt{"d": 3}.Or(Lt{"e": 4}), 88 "d<? OR e<?", 89 []interface{}{3, 4}, 90 }, 91 { 92 Lt{"e": Select("id").From("f").Where(Eq{"g": 1})}, 93 "e<(SELECT id FROM f WHERE g=?)", 94 []interface{}{1}, 95 }, 96 { 97 Lt{"e": Expr("SELECT id FROM f WHERE g=?", 1)}, 98 "e<(SELECT id FROM f WHERE g=?)", 99 []interface{}{1}, 100 }, 101 { 102 Lte{"d": 3}, 103 "d<=?", 104 []interface{}{3}, 105 }, 106 { 107 Lte{"d": 3}.And(Lte{"e": 4}), 108 "d<=? AND e<=?", 109 []interface{}{3, 4}, 110 }, 111 { 112 Lte{"d": 3}.Or(Lte{"e": 4}), 113 "d<=? OR e<=?", 114 []interface{}{3, 4}, 115 }, 116 { 117 Lte{"e": Select("id").From("f").Where(Eq{"g": 1})}, 118 "e<=(SELECT id FROM f WHERE g=?)", 119 []interface{}{1}, 120 }, 121 { 122 Lte{"e": Expr("SELECT id FROM f WHERE g=?", 1)}, 123 "e<=(SELECT id FROM f WHERE g=?)", 124 []interface{}{1}, 125 }, 126 { 127 Gt{"d": 3}, 128 "d>?", 129 []interface{}{3}, 130 }, 131 { 132 Gt{"d": 3}.And(Gt{"e": 4}), 133 "d>? AND e>?", 134 []interface{}{3, 4}, 135 }, 136 { 137 Gt{"d": 3}.Or(Gt{"e": 4}), 138 "d>? OR e>?", 139 []interface{}{3, 4}, 140 }, 141 { 142 Gt{"e": Select("id").From("f").Where(Eq{"g": 1})}, 143 "e>(SELECT id FROM f WHERE g=?)", 144 []interface{}{1}, 145 }, 146 { 147 Gt{"e": Expr("SELECT id FROM f WHERE g=?", 1)}, 148 "e>(SELECT id FROM f WHERE g=?)", 149 []interface{}{1}, 150 }, 151 { 152 Gte{"d": 3}, 153 "d>=?", 154 []interface{}{3}, 155 }, 156 { 157 Gte{"d": 3}.And(Gte{"e": 4}), 158 "d>=? AND e>=?", 159 []interface{}{3, 4}, 160 }, 161 { 162 Gte{"d": 3}.Or(Gte{"e": 4}), 163 "d>=? OR e>=?", 164 []interface{}{3, 4}, 165 }, 166 { 167 Gte{"e": Select("id").From("f").Where(Eq{"g": 1})}, 168 "e>=(SELECT id FROM f WHERE g=?)", 169 []interface{}{1}, 170 }, 171 { 172 Gte{"e": Expr("SELECT id FROM f WHERE g=?", 1)}, 173 "e>=(SELECT id FROM f WHERE g=?)", 174 []interface{}{1}, 175 }, 176 { 177 Between{"d", 0, 2}, 178 "d BETWEEN ? AND ?", 179 []interface{}{0, 2}, 180 }, 181 { 182 Between{"d", 0, Expr("CAST('2003-01-01' AS DATE)")}, 183 "d BETWEEN ? AND CAST('2003-01-01' AS DATE)", 184 []interface{}{0}, 185 }, 186 { 187 Between{"d", Expr("CAST('2003-01-01' AS DATE)"), 2}, 188 "d BETWEEN CAST('2003-01-01' AS DATE) AND ?", 189 []interface{}{2}, 190 }, 191 { 192 Between{"d", Expr("CAST('2003-01-01' AS DATE)"), Expr("CAST('2003-01-01' AS DATE)")}, 193 "d BETWEEN CAST('2003-01-01' AS DATE) AND CAST('2003-01-01' AS DATE)", 194 []interface{}{}, 195 }, 196 { 197 Between{"d", 0, 2}.And(Between{"e", 3, 4}), 198 "d BETWEEN ? AND ? AND e BETWEEN ? AND ?", 199 []interface{}{0, 2, 3, 4}, 200 }, 201 { 202 Between{"d", 0, 2}.Or(Between{"e", 3, 4}), 203 "d BETWEEN ? AND ? OR e BETWEEN ? AND ?", 204 []interface{}{0, 2, 3, 4}, 205 }, 206 { 207 Expr("a < ?", 1), 208 "a < ?", 209 []interface{}{1}, 210 }, 211 { 212 Expr("a < ?", 1).And(Eq{"b": 2}), 213 "(a < ?) AND b=?", 214 []interface{}{1, 2}, 215 }, 216 { 217 Expr("a < ?", 1).Or(Neq{"b": 2}), 218 "(a < ?) OR b<>?", 219 []interface{}{1, 2}, 220 }, 221 { 222 IsNull{"d"}, 223 "d IS NULL", 224 []interface{}{}, 225 }, 226 { 227 IsNull{"d"}.And(IsNull{"e"}), 228 "d IS NULL AND e IS NULL", 229 []interface{}{}, 230 }, 231 { 232 IsNull{"d"}.Or(IsNull{"e"}), 233 "d IS NULL OR e IS NULL", 234 []interface{}{}, 235 }, 236 { 237 NotNull{"d"}, 238 "d IS NOT NULL", 239 []interface{}{}, 240 }, 241 { 242 NotNull{"d"}.And(NotNull{"e"}), 243 "d IS NOT NULL AND e IS NOT NULL", 244 []interface{}{}, 245 }, 246 { 247 NotNull{"d"}.Or(NotNull{"e"}), 248 "d IS NOT NULL OR e IS NOT NULL", 249 []interface{}{}, 250 }, 251 { 252 NotIn("a", 1, 2).And(NotIn("b", "c", "d")), 253 "a NOT IN (?,?) AND b NOT IN (?,?)", 254 []interface{}{1, 2, "c", "d"}, 255 }, 256 { 257 In("a", 1, 2).Or(In("b", "c", "d")), 258 "a IN (?,?) OR b IN (?,?)", 259 []interface{}{1, 2, "c", "d"}, 260 }, 261 { 262 In("a", []int{1, 2}).Or(In("b", []string{"c", "d"})), 263 "a IN (?,?) OR b IN (?,?)", 264 []interface{}{1, 2, "c", "d"}, 265 }, 266 { 267 In("a", Expr("select id from x where name > ?", "b")), 268 "a IN (select id from x where name > ?)", 269 []interface{}{"b"}, 270 }, 271 { 272 In("a", []MyInt{1, 2}).Or(In("b", []string{"c", "d"})), 273 "a IN (?,?) OR b IN (?,?)", 274 []interface{}{MyInt(1), MyInt(2), "c", "d"}, 275 }, 276 { 277 In("a", []int{}), 278 "0=1", 279 []interface{}{}, 280 }, 281 { 282 In("a", []int{1}), 283 "a IN (?)", 284 []interface{}{1}, 285 }, 286 { 287 In("a", []int8{}), 288 "0=1", 289 []interface{}{}, 290 }, 291 { 292 In("a", []int8{1}), 293 "a IN (?)", 294 []interface{}{1}, 295 }, 296 { 297 In("a", []int16{}), 298 "0=1", 299 []interface{}{}, 300 }, 301 { 302 In("a", []int16{1}), 303 "a IN (?)", 304 []interface{}{1}, 305 }, 306 { 307 In("a", []int32{}), 308 "0=1", 309 []interface{}{}, 310 }, 311 { 312 In("a", []int32{1}), 313 "a IN (?)", 314 []interface{}{1}, 315 }, 316 { 317 In("a", []int64{}), 318 "0=1", 319 []interface{}{}, 320 }, 321 { 322 In("a", []int64{1}), 323 "a IN (?)", 324 []interface{}{1}, 325 }, 326 { 327 In("a", []uint{}), 328 "0=1", 329 []interface{}{}, 330 }, 331 { 332 In("a", []uint{1}), 333 "a IN (?)", 334 []interface{}{1}, 335 }, 336 { 337 In("a", []uint8{}), 338 "0=1", 339 []interface{}{}, 340 }, 341 { 342 In("a", []uint8{1}), 343 "a IN (?)", 344 []interface{}{1}, 345 }, 346 { 347 In("a", []uint16{}), 348 "0=1", 349 []interface{}{}, 350 }, 351 { 352 In("a", []uint16{1}), 353 "a IN (?)", 354 []interface{}{1}, 355 }, 356 { 357 In("a", []uint32{}), 358 "0=1", 359 []interface{}{}, 360 }, 361 { 362 In("a", []uint32{1}), 363 "a IN (?)", 364 []interface{}{1}, 365 }, 366 { 367 In("a", []uint64{}), 368 "0=1", 369 []interface{}{}, 370 }, 371 { 372 In("a", []uint64{1}), 373 "a IN (?)", 374 []interface{}{1}, 375 }, 376 { 377 In("a", []string{}), 378 "0=1", 379 []interface{}{}, 380 }, 381 { 382 In("a", []interface{}{}), 383 "0=1", 384 []interface{}{}, 385 }, 386 { 387 In("a", []MyInt{}), 388 "0=1", 389 []interface{}{}, 390 }, 391 { 392 In("a", []interface{}{1, 2, 3}).And(Eq{"b": "c"}), 393 "a IN (?,?,?) AND b=?", 394 []interface{}{1, 2, 3, "c"}, 395 }, 396 { 397 In("a", Select("id").From("b").Where(Eq{"c": 1})), 398 "a IN (SELECT id FROM b WHERE c=?)", 399 []interface{}{1}, 400 }, 401 { 402 NotIn("a", Expr("select id from x where name > ?", "b")), 403 "a NOT IN (select id from x where name > ?)", 404 []interface{}{"b"}, 405 }, 406 { 407 NotIn("a", []int{}), 408 "0=0", 409 []interface{}{}, 410 }, 411 { 412 NotIn("a", []int{1}), 413 "a NOT IN (?)", 414 []interface{}{1}, 415 }, 416 { 417 NotIn("a", []int8{}), 418 "0=0", 419 []interface{}{}, 420 }, 421 { 422 NotIn("a", []int8{1}), 423 "a NOT IN (?)", 424 []interface{}{1}, 425 }, 426 { 427 NotIn("a", []int16{}), 428 "0=0", 429 []interface{}{}, 430 }, 431 { 432 NotIn("a", []int16{1}), 433 "a NOT IN (?)", 434 []interface{}{1}, 435 }, 436 { 437 NotIn("a", []int32{}), 438 "0=0", 439 []interface{}{}, 440 }, 441 { 442 NotIn("a", []int32{1}), 443 "a NOT IN (?)", 444 []interface{}{1}, 445 }, 446 { 447 NotIn("a", []int64{}), 448 "0=0", 449 []interface{}{}, 450 }, 451 { 452 NotIn("a", []int64{1}), 453 "a NOT IN (?)", 454 []interface{}{1}, 455 }, 456 { 457 NotIn("a", []uint{}), 458 "0=0", 459 []interface{}{}, 460 }, 461 { 462 NotIn("a", []uint{1}), 463 "a NOT IN (?)", 464 []interface{}{1}, 465 }, 466 { 467 NotIn("a", []uint8{}), 468 "0=0", 469 []interface{}{}, 470 }, 471 { 472 NotIn("a", []uint8{1}), 473 "a NOT IN (?)", 474 []interface{}{1}, 475 }, 476 { 477 NotIn("a", []uint16{}), 478 "0=0", 479 []interface{}{}, 480 }, 481 { 482 NotIn("a", []uint16{1}), 483 "a NOT IN (?)", 484 []interface{}{1}, 485 }, 486 { 487 NotIn("a", []uint32{}), 488 "0=0", 489 []interface{}{}, 490 }, 491 { 492 NotIn("a", []uint32{1}), 493 "a NOT IN (?)", 494 []interface{}{1}, 495 }, 496 { 497 NotIn("a", []uint64{}), 498 "0=0", 499 []interface{}{}, 500 }, 501 { 502 NotIn("a", []uint64{1}), 503 "a NOT IN (?)", 504 []interface{}{1}, 505 }, 506 { 507 NotIn("a", []interface{}{}), 508 "0=0", 509 []interface{}{}, 510 }, 511 { 512 NotIn("a", []string{}), 513 "0=0", 514 []interface{}{}, 515 }, 516 { 517 NotIn("a", []MyInt{}), 518 "0=0", 519 []interface{}{}, 520 }, 521 { 522 NotIn("a", []MyInt{1, 2}), 523 "a NOT IN (?,?)", 524 []interface{}{1, 2}, 525 }, 526 { 527 NotIn("a", []interface{}{1, 2, 3}).And(Eq{"b": "c"}), 528 "a NOT IN (?,?,?) AND b=?", 529 []interface{}{1, 2, 3, "c"}, 530 }, 531 { 532 NotIn("a", []interface{}{1, 2, 3}).Or(Eq{"b": "c"}), 533 "a NOT IN (?,?,?) OR b=?", 534 []interface{}{1, 2, 3, "c"}, 535 }, 536 { 537 NotIn("a", Select("id").From("b").Where(Eq{"c": 1})), 538 "a NOT IN (SELECT id FROM b WHERE c=?)", 539 []interface{}{1}, 540 }, 541 { 542 Or(Eq{"a": 1, "b": 2}, Eq{"c": 3, "d": 4}), 543 "(a=? AND b=?) OR (c=? AND d=?)", 544 []interface{}{1, 2, 3, 4}, 545 }, 546 { 547 Not{Eq{"a": 1, "b": 2}}, 548 "NOT (a=? AND b=?)", 549 []interface{}{1, 2}, 550 }, 551 { 552 Not{Neq{"a": 1, "b": 2}}, 553 "NOT (a<>? AND b<>?)", 554 []interface{}{1, 2}, 555 }, 556 { 557 Not{Eq{"a": 1}.And(Eq{"b": 2})}, 558 "NOT (a=? AND b=?)", 559 []interface{}{1, 2}, 560 }, 561 { 562 Not{Neq{"a": 1}.And(Neq{"b": 2})}, 563 "NOT (a<>? AND b<>?)", 564 []interface{}{1, 2}, 565 }, 566 { 567 Not{Eq{"a": 1}}.And(Neq{"b": 2}), 568 "NOT a=? AND b<>?", 569 []interface{}{1, 2}, 570 }, 571 { 572 Not{Eq{"a": 1}}.Or(Neq{"b": 2}), 573 "NOT a=? OR b<>?", 574 []interface{}{1, 2}, 575 }, 576 } 577 578 for _, k := range cases { 579 sql, args, err := ToSQL(k.cond) 580 assert.NoError(t, err) 581 assert.EqualValues(t, k.sql, sql) 582 583 for i := 0; i < 10; i++ { 584 sql2, _, err := ToSQL(k.cond) 585 assert.NoError(t, err) 586 assert.EqualValues(t, sql, sql2) 587 } 588 589 assert.EqualValues(t, len(args), len(k.args)) 590 591 if len(args) > 0 { 592 for i := 0; i < len(args); i++ { 593 assert.EqualValues(t, k.args[i], args[i]) 594 } 595 } 596 } 597 } 598 599 func TestSubquery(t *testing.T) { 600 subb := Select("id").From("table_b").Where(Eq{"b": "a"}) 601 b := Select("a, b").From("table_a").Where( 602 Eq{ 603 "b_id": subb, 604 "id": 23, 605 }, 606 ) 607 sql, args, err := b.ToSQL() 608 assert.NoError(t, err) 609 assert.EqualValues(t, "SELECT a, b FROM table_a WHERE b_id=(SELECT id FROM table_b WHERE b=?) AND id=?", sql) 610 assert.EqualValues(t, []interface{}{"a", 23}, args) 611 } 612 613 // https://github.com/go-xorm/xorm/issues/820 614 func TestExprCond(t *testing.T) { 615 b := Select("id").From("table1").Where(expr{sql: "a=? OR b=?", args: []interface{}{1, 2}}).Where(Or(Eq{"c": 3}, Eq{"d": 4})) 616 sql, args, err := b.ToSQL() 617 assert.NoError(t, err) 618 assert.EqualValues(t, "table1", b.TableName()) 619 assert.EqualValues(t, "SELECT id FROM table1 WHERE (a=? OR b=?) AND (c=? OR d=?)", sql) 620 assert.EqualValues(t, []interface{}{1, 2, 3, 4}, args) 621 } 622 623 func TestBuilder_ToBoundSQL(t *testing.T) { 624 newSQL, err := Select("id").From("table").Where(In("a", 1, 2)).ToBoundSQL() 625 assert.NoError(t, err) 626 assert.EqualValues(t, "SELECT id FROM table WHERE a IN (1,2)", newSQL) 627 } 628 629 func TestBuilder_From2(t *testing.T) { 630 b := Select("id").From("table_b", "tb").Where(Eq{"b": "a"}) 631 sql, args, err := b.ToSQL() 632 assert.NoError(t, err) 633 assert.EqualValues(t, "SELECT id FROM table_b tb WHERE b=?", sql) 634 assert.EqualValues(t, []interface{}{"a"}, args) 635 636 b = Select().From("table_b", "tb").Where(Eq{"b": "a"}) 637 sql, args, err = b.ToSQL() 638 assert.NoError(t, err) 639 assert.EqualValues(t, "SELECT * FROM table_b tb WHERE b=?", sql) 640 assert.EqualValues(t, []interface{}{"a"}, args) 641 } 642 643 func TestBuilder_And(t *testing.T) { 644 b := Select("id").From("table_b", "tb").Where(Eq{"b": "a"}).And(Neq{"c": "d"}) 645 sql, args, err := b.ToSQL() 646 assert.NoError(t, err) 647 assert.EqualValues(t, "SELECT id FROM table_b tb WHERE b=? AND c<>?", sql) 648 assert.EqualValues(t, []interface{}{"a", "d"}, args) 649 } 650 651 func TestBuilder_Or(t *testing.T) { 652 b := Select("id").From("table_b", "tb").Where(Eq{"b": "a"}).Or(Neq{"c": "d"}) 653 sql, args, err := b.ToSQL() 654 assert.NoError(t, err) 655 assert.EqualValues(t, "SELECT id FROM table_b tb WHERE b=? OR c<>?", sql) 656 assert.EqualValues(t, []interface{}{"a", "d"}, args) 657 }