$this->query( "SET client_encoding='UTF8'", __METHOD__ );
$this->query( "SET datestyle = 'ISO, YMD'", __METHOD__ );
$this->query( "SET timezone = 'GMT'", __METHOD__ );
+ $this->query( "SET standard_conforming_strings = on", __METHOD__ );
global $wgDBmwschema;
if ( $this->schemaExists( $wgDBmwschema ) ) {
$ignore = in_array( 'IGNORE', $insertOptions ) ? 'mw' : '';
if( is_array( $insertOptions ) ) {
- $insertOptions = implode( ' ', $insertOptions );
+ $insertOptions = implode( ' ', $insertOptions ); // FIXME: This is unused
}
if( !is_array( $selectOptions ) ) {
$selectOptions = array( $selectOptions );
}
function tableName( $name, $format = 'quoted' ) {
- # Replace reserved words with better ones
- switch( $name ) {
+ global $wgSharedDB, $wgSharedTables;
+ # Skip quoted tablenames.
+ if ( $this->isQuotedIdentifier( $name ) ) {
+ return $name;
+ }
+ # Lets test for any bits of text that should never show up in a table
+ # name. Basically anything like JOIN or ON which are actually part of
+ # SQL queries, but may end up inside of the table value to combine
+ # sql. Such as how the API is doing.
+ # Note that we use a whitespace test rather than a \b test to avoid
+ # any remote case where a word like on may be inside of a table name
+ # surrounded by symbols which may be considered word breaks.
+ if ( preg_match( '/(^|\s)(DISTINCT|JOIN|ON|AS)(\s|$)/i', $name ) !== 0 ) {
+ return $name;
+ }
+ # Extract the database prefix, if any and quote it
+ $dbDetails = explode( '.', $name, 2 );
+ if ( isset( $dbDetails[1] ) ) {
+ $schema = '"' . $dbDetails[0] . '".';
+ $table = $dbDetails[1];
+ } else {
+ $schema = ""; # do NOT force the schema (due to temporary tables)
+ $table = $dbDetails[0];
+ }
+ if ( $format != 'quoted' ) {
+ switch( $name ) {
+ case 'user':
+ return 'mwuser';
+ case 'text':
+ return 'pagecontent';
+ default:
+ return $table;
+ }
+ }
+
+ if ( isset( $wgSharedDB ) # We have a shared database (=> schema)
+ && isset( $wgSharedTables )
+ && is_array( $wgSharedTables )
+ && in_array( $table, $wgSharedTables ) ) { # A shared table is selected
+ $schema = "\"{$wgSharedDB}\".";
+ }
+ switch ( $table ) {
case 'user':
- return 'mwuser';
+ $table = "{$schema}\"mwuser\"";
+ break;
case 'text':
- return 'pagecontent';
+ $table = "{$schema}\"pagecontent\"";
+ break;
default:
- return parent::tableName( $name, $format );
+ $table = "{$schema}\"$table\"";
+ break;
}
+ return $table;
}
/**
return $this->query( 'CREATE ' . ( $temporary ? 'TEMPORARY ' : '' ) . " TABLE $newName (LIKE $oldName INCLUDING DEFAULTS)", $fname );
}
+ function listTables( $prefix = null, $fname = 'DatabasePostgres::listTables' ) {
+ global $wgDBmwschema;
+ $eschema = $this->addQuotes( $wgDBmwschema );
+ $result = $this->query( "SELECT tablename FROM pg_tables WHERE schemaname = $eschema", $fname );
+
+ $endArray = array();
+
+ foreach( $result as $table ) {
+ $vars = get_object_vars($table);
+ $table = array_pop( $vars );
+ if( !$prefix || strpos( $table, $prefix ) === 0 ) {
+ $endArray[] = $table;
+ }
+ }
+
+ return $endArray;
+ }
+
function timestamp( $ts = 0 ) {
return wfTimestamp( TS_POSTGRES, $ts );
}
* For backward compatibility, this function checks both tables and
* views.
*/
- function tableExists( $table, $schema = false ) {
+ function tableExists( $table, $fname = __METHOD__, $schema = false ) {
return $this->relationExists( $table, array( 'r', 'v' ), $schema );
}
} elseif ( is_bool( $s ) ) {
return intval( $s );
} elseif ( $s instanceof Blob ) {
- $ret = "'" . $s->fetch( $s ) . "'";
- if ( $this->numeric_version >= 8.1 ) {
- $ret = "E$ret";
- }
- return $ret;
+ return "'" . $s->fetch( $s ) . "'";
}
return "'" . pg_escape_string( $this->mConn, $s ) . "'";
}
public function getSearchEngine() {
return 'SearchPostgres';
}
+
+ public function streamStatementEnd( &$sql, &$newLine ) {
+ # Allow dollar quoting for function declarations
+ if ( substr( $newLine, 0, 4 ) == '$mw$' ) {
+ if ( $this->delimiter ) {
+ $this->delimiter = false;
+ }
+ else {
+ $this->delimiter = ';';
+ }
+ }
+ return parent::streamStatementEnd( $sql, $newLine );
+ }
} // end DatabasePostgres class