Index: trunk/phase3/tests/DatabaseTest.php |
— | — | @@ -0,0 +1,60 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +require_once( 'PHPUnit.php' ); |
| 5 | +require_once( '../includes/Defines.php' ); |
| 6 | +require_once( '../includes/Database.php' ); |
| 7 | +require_once( '../includes/GlobalFunctions.php' ); |
| 8 | + |
| 9 | +class DatabaseTest extends PHPUnit_TestCase { |
| 10 | + var $db; |
| 11 | + |
| 12 | + function DatabaseTest( $name ) { |
| 13 | + $this->PHPUnit_TestCase( $name ); |
| 14 | + } |
| 15 | + |
| 16 | + function setUp() { |
| 17 | + $this->db =& new Database(); |
| 18 | + } |
| 19 | + |
| 20 | + function tearDown() { |
| 21 | + unset( $this->db ); |
| 22 | + } |
| 23 | + |
| 24 | + function testFillPreparedEmpty() { |
| 25 | + $sql = $this->db->fillPrepared( |
| 26 | + 'SELECT * FROM interwiki', array() ); |
| 27 | + $this->assertEquals( |
| 28 | + "SELECT * FROM interwiki", |
| 29 | + $sql); |
| 30 | + } |
| 31 | + |
| 32 | + function testFillPreparedQuestion() { |
| 33 | + $sql = $this->db->fillPrepared( |
| 34 | + 'SELECT * FROM cur WHERE cur_namespace=? AND cur_title=?', |
| 35 | + array( 4, "Snicker's_paradox" ) ); |
| 36 | + $this->assertEquals( |
| 37 | + "SELECT * FROM cur WHERE cur_namespace='4' AND cur_title='Snicker\'s_paradox'", |
| 38 | + $sql); |
| 39 | + } |
| 40 | + |
| 41 | + function testFillPreparedBang() { |
| 42 | + $sql = $this->db->fillPrepared( |
| 43 | + 'SELECT user_id FROM ! WHERE user_name=?', |
| 44 | + array( '"user"', "Slash's Dot" ) ); |
| 45 | + $this->assertEquals( |
| 46 | + "SELECT user_id FROM \"user\" WHERE user_name='Slash\'s Dot'", |
| 47 | + $sql); |
| 48 | + } |
| 49 | + |
| 50 | + function testFillPreparedRaw() { |
| 51 | + $sql = $this->db->fillPrepared( |
| 52 | + "SELECT * FROM cur WHERE cur_title='This_\\&_that,_WTF\\?\\!'", |
| 53 | + array( '"user"', "Slash's Dot" ) ); |
| 54 | + $this->assertEquals( |
| 55 | + "SELECT * FROM cur WHERE cur_title='This_&_that,_WTF?!'", |
| 56 | + $sql); |
| 57 | + } |
| 58 | + |
| 59 | +} |
| 60 | + |
| 61 | +?> |
\ No newline at end of file |
Property changes on: trunk/phase3/tests/DatabaseTest.php |
___________________________________________________________________ |
Added: svn:keywords |
1 | 62 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 63 | + native |
Index: trunk/phase3/tests/RunTests.php |
— | — | @@ -0,0 +1,12 @@ |
| 2 | +<?php |
| 3 | +error_reporting( E_ALL ); |
| 4 | +define( "MEDIAWIKI", true ); |
| 5 | + |
| 6 | +require_once( 'PHPUnit.php' ); |
| 7 | +require_once( 'DatabaseTest.php' ); |
| 8 | + |
| 9 | +$suite = new PHPUnit_TestSuite( "DatabaseTest" ); |
| 10 | +$result = PHPUnit::run( $suite ); |
| 11 | +echo $result->toString(); |
| 12 | + |
| 13 | +?> |
\ No newline at end of file |
Property changes on: trunk/phase3/tests/RunTests.php |
___________________________________________________________________ |
Added: svn:keywords |
1 | 14 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 15 | + native |
Index: trunk/phase3/includes/Database.php |
— | — | @@ -352,6 +352,100 @@ |
353 | 353 | } |
354 | 354 | |
355 | 355 | |
| 356 | + /** |
| 357 | + * Intended to be compatible with the PEAR::DB wrapper functions. |
| 358 | + * http://pear.php.net/manual/en/package.database.db.intro-execute.php |
| 359 | + * |
| 360 | + * ? = scalar value, quoted as necessary |
| 361 | + * ! = raw SQL bit (a function for instance) |
| 362 | + * & = filename; reads the file and inserts as a blob |
| 363 | + * (we don't use this though...) |
| 364 | + */ |
| 365 | + function prepare( $sql, $func = 'Database::prepare' ) { |
| 366 | + /* MySQL doesn't support prepared statements (yet), so just |
| 367 | + pack up the query for reference. We'll manually replace |
| 368 | + the bits later. */ |
| 369 | + return array( 'query' => $sql, 'func' => $func ); |
| 370 | + } |
| 371 | + |
| 372 | + function freePrepared( $prepared ) { |
| 373 | + /* No-op for MySQL */ |
| 374 | + } |
| 375 | + |
| 376 | + /** |
| 377 | + * Execute a prepared query with the various arguments |
| 378 | + * @param string $prepared the prepared sql |
| 379 | + * @param mixed $args Either an array here, or put scalars as varargs |
| 380 | + */ |
| 381 | + function execute( $prepared, $args = null ) { |
| 382 | + if( !is_array( $args ) ) { |
| 383 | + # Pull the var args |
| 384 | + $args = func_get_args(); |
| 385 | + array_shift( $args ); |
| 386 | + } |
| 387 | + $sql = $this->fillPrepared( $prepared['query'], $args ); |
| 388 | + return $this->query( $sql, $prepared['func'] ); |
| 389 | + } |
| 390 | + |
| 391 | + /** |
| 392 | + * Prepare & execute an SQL statement, quoting and inserting arguments |
| 393 | + * in the appropriate places. |
| 394 | + * @param |
| 395 | + */ |
| 396 | + function safeQuery( $query, $args = null ) { |
| 397 | + $prepared = $this->prepare( $query, 'Database::safeQuery' ); |
| 398 | + if( !is_array( $args ) ) { |
| 399 | + # Pull the var args |
| 400 | + $args = func_get_args(); |
| 401 | + array_shift( $args ); |
| 402 | + } |
| 403 | + $retval = $this->execute( $prepared, $args ); |
| 404 | + $this->freePrepared( $prepared ); |
| 405 | + return $retval; |
| 406 | + } |
| 407 | + |
| 408 | + /** |
| 409 | + * For faking prepared SQL statements on DBs that don't support |
| 410 | + * it directly. |
| 411 | + * @param string $preparedSql - a 'preparable' SQL statement |
| 412 | + * @param array $args - array of arguments to fill it with |
| 413 | + * @return string executable SQL |
| 414 | + */ |
| 415 | + function fillPrepared( $preparedQuery, $args ) { |
| 416 | + $n = 0; |
| 417 | + reset( $args ); |
| 418 | + $this->preparedArgs =& $args; |
| 419 | + return preg_replace_callback( '/(\\\\[?!&]|[?!&])/', |
| 420 | + array( &$this, 'fillPreparedArg' ), $preparedQuery ); |
| 421 | + } |
| 422 | + |
| 423 | + /** |
| 424 | + * preg_callback func for fillPrepared() |
| 425 | + * The arguments should be in $this->preparedArgs and must not be touched |
| 426 | + * while we're doing this. |
| 427 | + * |
| 428 | + * @param array $matches |
| 429 | + * @return string |
| 430 | + * @access private |
| 431 | + */ |
| 432 | + function fillPreparedArg( $matches ) { |
| 433 | + switch( $matches[1] ) { |
| 434 | + case '\\?': return '?'; |
| 435 | + case '\\!': return '!'; |
| 436 | + case '\\&': return '&'; |
| 437 | + } |
| 438 | + list( $n, $arg ) = each( $this->preparedArgs ); |
| 439 | + switch( $matches[1] ) { |
| 440 | + case '?': return $this->addQuotes( $arg ); |
| 441 | + case '!': return $arg; |
| 442 | + case '&': |
| 443 | + # return $this->addQuotes( file_get_contents( $arg ) ); |
| 444 | + wfDebugDieBacktrace( '& mode is not implemented. If it\'s really needed, uncomment the line above.' ); |
| 445 | + default: |
| 446 | + wfDebugDieBacktrace( 'Received invalid match. This should never happen!' ); |
| 447 | + } |
| 448 | + } |
| 449 | + |
356 | 450 | /**#@+ |
357 | 451 | * @param mixed $res A SQL result |
358 | 452 | */ |