X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fdb%2FDatabase.php;h=7248bb99856908c969b1c391f2a182b70baa31da;hb=692ad26f682ae09805c0aafdbb86faafab555c72;hp=c9a45e1715abc4af1597568fc39aae5fd904a9db;hpb=f134f2f134c67a5db9dc170ae370a84b5a97fd8c;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/db/Database.php b/includes/db/Database.php index c9a45e1715..7248bb9985 100644 --- a/includes/db/Database.php +++ b/includes/db/Database.php @@ -604,7 +604,7 @@ abstract class DatabaseBase implements DatabaseType { * comment (you can use __METHOD__ or add some extra info) * @param $tempIgnore Boolean: Whether to avoid throwing an exception on errors... * maybe best to catch the exception instead? - * @return true for a successful write query, ResultWrapper object for a successful read query, + * @return boolean or ResultWrapper. true for a successful write query, ResultWrapper object for a successful read query, * or false on failure if $tempIgnore set * @throws DBQueryError Thrown when the database returns an error of any kind */ @@ -1012,7 +1012,7 @@ abstract class DatabaseBase implements DatabaseType { /** * SELECT wrapper * - * @param $table Mixed: Array or string, table name(s) (prefix auto-added) + * @param $table Mixed: Array or string, table name(s) (prefix auto-added). Array keys are table aliases (optional) * @param $vars Mixed: Array or string, field name(s) to be retrieved * @param $conds Mixed: Array or string, condition(s) for WHERE * @param $fname String: Calling function name (use __METHOD__) for logs/profiling @@ -1035,7 +1035,7 @@ abstract class DatabaseBase implements DatabaseType { if ( !empty( $join_conds ) || ( isset( $options['USE INDEX'] ) && is_array( @$options['USE INDEX'] ) ) ) { $from = ' FROM ' . $this->tableNamesWithUseIndexOrJOIN( $table, @$options['USE INDEX'], $join_conds ); } else { - $from = ' FROM ' . implode( ',', array_map( array( &$this, 'tableName' ), $table ) ); + $from = ' FROM ' . implode( ',', $this->tableNamesWithAlias( $table ) ); } } elseif ( $table != '' ) { if ( $table { 0 } == ' ' ) { @@ -1575,6 +1575,39 @@ abstract class DatabaseBase implements DatabaseType { return $retVal; } + /** + * Get an aliased table name + * e.g. tableName AS newTableName + * + * @param $name string Table name, see tableName() + * @param $alias string Alias (optional) + * @return string SQL name for aliased table. Will not alias a table to its own name + */ + public function tableNameWithAlias( $name, $alias = false ) { + if ( !$alias || $alias == $name ) { + return $this->tableName( $name ); + } else { + return $this->tableName( $name ) . ' `' . $alias . '`'; + } + } + + /** + * Gets an array of aliased table names + * + * @param $tables array( [alias] => table ) + * @return array of strings, see tableNameWithAlias() + */ + public function tableNamesWithAlias( $tables ) { + $retval = array(); + foreach ( $tables as $alias => $table ) { + if ( is_numeric( $alias ) ) { + $alias = $table; + } + $retval[] = $this->tableNameWithAlias( $table, $alias ); + } + return $retval; + } + /** * @private */ @@ -1584,35 +1617,37 @@ abstract class DatabaseBase implements DatabaseType { $use_index_safe = is_array( $use_index ) ? $use_index : array(); $join_conds_safe = is_array( $join_conds ) ? $join_conds : array(); - foreach ( $tables as $table ) { + foreach ( $tables as $alias => $table ) { + if ( !is_string( $alias ) ) { + // No alias? Set it equal to the table name + $alias = $table; + } // Is there a JOIN and INDEX clause for this table? - if ( isset( $join_conds_safe[$table] ) && isset( $use_index_safe[$table] ) ) { - $tableClause = $join_conds_safe[$table][0] . ' ' . $this->tableName( $table ); - $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$table] ) ); - $on = $this->makeList( (array)$join_conds_safe[$table][1], LIST_AND ); - + if ( isset( $join_conds_safe[$alias] ) && isset( $use_index_safe[$alias] ) ) { + $tableClause = $join_conds_safe[$alias][0] . ' ' . $this->tableNameWithAlias( $table, $alias ); + $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$alias] ) ); + $on = $this->makeList( (array)$join_conds_safe[$alias][1], LIST_AND ); if ( $on != '' ) { $tableClause .= ' ON (' . $on . ')'; } $retJOIN[] = $tableClause; // Is there an INDEX clause? - } else if ( isset( $use_index_safe[$table] ) ) { - $tableClause = $this->tableName( $table ); - $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$table] ) ); + } else if ( isset( $use_index_safe[$alias] ) ) { + $tableClause = $this->tableNameWithAlias( $table, $alias ); + $tableClause .= ' ' . $this->useIndexClause( implode( ',', (array)$use_index_safe[$alias] ) ); $ret[] = $tableClause; // Is there a JOIN clause? - } else if ( isset( $join_conds_safe[$table] ) ) { - $tableClause = $join_conds_safe[$table][0] . ' ' . $this->tableName( $table ); - $on = $this->makeList( (array)$join_conds_safe[$table][1], LIST_AND ); - + } else if ( isset( $join_conds_safe[$alias] ) ) { + $tableClause = $join_conds_safe[$alias][0] . ' ' . $this->tableNameWithAlias( $table, $alias ); + $on = $this->makeList( (array)$join_conds_safe[$alias][1], LIST_AND ); if ( $on != '' ) { $tableClause .= ' ON (' . $on . ')'; } $retJOIN[] = $tableClause; } else { - $tableClause = $this->tableName( $table ); + $tableClause = $this->tableNameWithAlias( $table, $alias ); $ret[] = $tableClause; } } @@ -1659,6 +1694,26 @@ abstract class DatabaseBase implements DatabaseType { } } + /** + * Quotes a string using `backticks` for things like database, table, and field + * names, other databases which use something other than backticks can replace + * this with something else + */ + public function addIdentifierQuotes( $s ) { + return "`" . $this->strencode( $s ) . "`"; + } + + /** + * Backwards compatibility, identifier quoting originated in DatabasePostgres + * which used quote_ident which does not follow our naming conventions + * was renamed to addIdentifierQuotes. + * @deprecated use addIdentifierQuotes + */ + function quote_ident( $s ) { + wfDeprecated( __METHOD__ ); + return $this->addIdentifierQuotes( $s ); + } + /** * Escape string for safe LIKE usage. * WARNING: you should almost never use this function directly, @@ -1988,6 +2043,16 @@ abstract class DatabaseBase implements DatabaseType { return "REPLACE({$orig}, {$old}, {$new})"; } + /** + * Convert a field to an unix timestamp + * + * @param $field String: field name + * @return String: SQL statement + */ + public function unixTimestamp( $field ) { + return "EXTRACT(epoch FROM $field)"; + } + /** * Determines if the last failure was due to a deadlock * STUB @@ -2455,6 +2520,32 @@ abstract class DatabaseBase implements DatabaseType { return true; } + /** + * Database independent variable replacement, replaces a set of named variables + * in a sql statement with the contents of their global variables. + * Supports '{$var}' `{$var}` and / *$var* / (without the spaces) style variables + * + * '{$var}' should be used for text and is passed through the database's addQuotes method + * `{$var}` should be used for identifiers (eg: table and database names), it is passed through + * the database's addIdentifierQuotes method which can be overridden if the database + * uses something other than backticks. + * / *$var* / is just encoded, besides traditional dbprefix and tableoptions it's use should be avoided + * + * @param $ins String: SQL statement to replace variables in + * @param $varnames Array: Array of global variable names to replace + * @return String The new SQL statement with variables replaced + */ + protected function replaceGlobalVars( $ins, $varnames ) { + foreach ( $varnames as $var ) { + if ( isset( $GLOBALS[$var] ) ) { + $ins = str_replace( '\'{$' . $var . '}\'', $this->addQuotes( $GLOBALS[$var] ), $ins ); // replace '{$var}' + $ins = str_replace( '`{$' . $var . '}`', $this->addIdentifierQuotes( $GLOBALS[$var] ), $ins ); // replace `{$var}` + $ins = str_replace( '/*$' . $var . '*/', $this->strencode( $GLOBALS[$var] ) , $ins ); // replace /*$var*/ + } + } + return $ins; + } + /** * Replace variables in sourced SQL */ @@ -2465,15 +2556,7 @@ abstract class DatabaseBase implements DatabaseType { 'wgDBadminuser', 'wgDBadminpassword', 'wgDBTableOptions', ); - // Ordinary variables - foreach ( $varnames as $var ) { - if ( isset( $GLOBALS[$var] ) ) { - $val = addslashes( $GLOBALS[$var] ); // FIXME: safety check? - $ins = str_replace( '{$' . $var . '}', $val, $ins ); - $ins = str_replace( '/*$' . $var . '*/`', '`' . $val, $ins ); - $ins = str_replace( '/*$' . $var . '*/', $val, $ins ); - } - } + $ins = $this->replaceGlobalVars( $ins, $varnames ); // Table prefixes $ins = preg_replace_callback( '!/\*(?:\$wgDBprefix|_)\*/([a-zA-Z_0-9]*)!', @@ -2795,7 +2878,7 @@ class DBConnectionError extends DBError { } function searchForm() { - global $wgSitename, $wgServer, $wgLang, $wgInputEncoding; + global $wgSitename, $wgServer, $wgLang; $usegoogle = "You can try searching via Google in the meantime."; $outofdate = "Note that their indexes of our content may be out of date."; @@ -2809,20 +2892,23 @@ class DBConnectionError extends DBError { $search = htmlspecialchars( @$_REQUEST['search'] ); + $server = htmlspecialchars( $wgServer ); + $sitename = htmlspecialchars( $wgSitename ); + $trygoogle = <<$usegoogle
$outofdate
- + - - + +
- +