Index: trunk/phase3/tests/phpunit/includes/db/DatabaseTest.php |
— | — | @@ -90,6 +90,34 @@ |
91 | 91 | $sql ); |
92 | 92 | } |
93 | 93 | |
| 94 | + function testMakeNotInList() { |
| 95 | + $this->assertEquals( |
| 96 | + $this->db->makeList( array( |
| 97 | + 'field' => array( 0, 1 ) |
| 98 | + ) ), |
| 99 | + "field IN ('0','1')" |
| 100 | + ); |
| 101 | + $this->assertEquals( |
| 102 | + $this->db->makeList( array( |
| 103 | + 'field!' => array( 0, 1 ) |
| 104 | + ) ), |
| 105 | + "field NOT IN ('0','1')" |
| 106 | + ); |
| 107 | + |
| 108 | + // make sure an array with only one value use = or != |
| 109 | + $this->assertEquals( |
| 110 | + $this->db->makeList( array( |
| 111 | + 'field' => array( 777 ) |
| 112 | + ) ), |
| 113 | + "field = 777" |
| 114 | + ); |
| 115 | + $this->assertEquals( |
| 116 | + $this->db->makeList( array( |
| 117 | + 'field!' => array( 888 ) |
| 118 | + ) ), |
| 119 | + "field != 888" |
| 120 | + ); |
| 121 | + } |
94 | 122 | } |
95 | 123 | |
96 | 124 | |
Index: trunk/phase3/includes/db/Database.php |
— | — | @@ -1382,6 +1382,13 @@ |
1383 | 1383 | * LIST_SET - comma separated with field names, like a SET clause |
1384 | 1384 | * LIST_NAMES - comma separated field names |
1385 | 1385 | * |
| 1386 | + * In LIST_AND or LIST_OR modes, you can suffix a field with an exclamation |
| 1387 | + * mark to generate a 'NOT IN' structure. |
| 1388 | + * Example: |
| 1389 | + * $db->makeList( array( 'field!' => array( 1,2,3 ) ); |
| 1390 | + * outputs: |
| 1391 | + * 'field' NOT IN ('1', '2', '3' ); |
| 1392 | + |
1386 | 1393 | * @return string |
1387 | 1394 | */ |
1388 | 1395 | function makeList( $a, $mode = LIST_COMMA ) { |
— | — | @@ -1405,6 +1412,13 @@ |
1406 | 1413 | $first = false; |
1407 | 1414 | } |
1408 | 1415 | |
| 1416 | + // Support 'NOT IN' by suffixing fieldname with an exclamation mark |
| 1417 | + $not = false; |
| 1418 | + if( substr($field,-1) == '!' ) { |
| 1419 | + $not = true; |
| 1420 | + $field = substr($field, 0, -1 ); |
| 1421 | + } |
| 1422 | + |
1409 | 1423 | if ( ( $mode == LIST_AND || $mode == LIST_OR ) && is_numeric( $field ) ) { |
1410 | 1424 | $list .= "($value)"; |
1411 | 1425 | } elseif ( ( $mode == LIST_SET ) && is_numeric( $field ) ) { |
— | — | @@ -1417,9 +1431,12 @@ |
1418 | 1432 | // Don't necessarily assume the single key is 0; we don't |
1419 | 1433 | // enforce linear numeric ordering on other arrays here. |
1420 | 1434 | $value = array_values( $value ); |
1421 | | - $list .= $field . " = " . $this->addQuotes( $value[0] ); |
| 1435 | + |
| 1436 | + $operator = $not ? ' != ' : ' = '; |
| 1437 | + $list .= $field . $operator . $this->addQuotes( $value[0] ); |
1422 | 1438 | } else { |
1423 | | - $list .= $field . " IN (" . $this->makeList( $value ) . ") "; |
| 1439 | + $operator = $not ? ' NOT IN ' : ' IN '; |
| 1440 | + $list .= $field . $operator . " (" . $this->makeList( $value ) . ") "; |
1424 | 1441 | } |
1425 | 1442 | } elseif ( $value === null ) { |
1426 | 1443 | if ( $mode == LIST_AND || $mode == LIST_OR ) { |