r58179 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r58178‎ | r58179 | r58180 >
Date:05:33, 27 October 2009
Author:overlordq
Status:ok
Tags:
Comment:
(bug 18909) Add missing INSERT SELECT wrapper for Postgres
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/db/DatabasePostgres.php (modified) (history)

Diff [purge]

Index: trunk/phase3/RELEASE-NOTES
@@ -601,6 +601,7 @@
602602 * User::isValidPassword now only returns boolean results, User::getPasswordValidity
603603 can be used to get an error message string
604604 * The error message shown in Special:ChangePassword now parses wiki markup
 605+* (bug 18909) Add missing Postgres INSERT SELECT wrapper
605606
606607 == API changes in 1.16 ==
607608
Index: trunk/phase3/includes/db/DatabasePostgres.php
@@ -873,6 +873,81 @@
874874
875875 }
876876
 877+ /**
 878+ * INSERT SELECT wrapper
 879+ * $varMap must be an associative array of the form array( 'dest1' => 'source1', ...)
 880+ * Source items may be literals rather then field names, but strings should be quoted with Database::addQuotes()
 881+ * $conds may be "*" to copy the whole table
 882+ * srcTable may be an array of tables.
 883+ * @todo FIXME: implement this a little better (seperate select/insert)?
 884+ */
 885+ function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = 'DatabasePostgres::insertSelect',
 886+ $insertOptions = array(), $selectOptions = array() )
 887+ {
 888+ $destTable = $this->tableName( $destTable );
 889+
 890+ // If IGNORE is set, we use savepoints to emulate mysql's behavior
 891+ $ignore = in_array( 'IGNORE', $insertOptions ) ? 'mw' : '';
 892+
 893+ if( is_array( $insertOptions ) ) {
 894+ $insertOptions = implode( ' ', $insertOptions );
 895+ }
 896+ if( !is_array( $selectOptions ) ) {
 897+ $selectOptions = array( $selectOptions );
 898+ }
 899+ list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
 900+ if( is_array( $srcTable ) ) {
 901+ $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
 902+ } else {
 903+ $srcTable = $this->tableName( $srcTable );
 904+ }
 905+
 906+ // If we are not in a transaction, we need to be for savepoint trickery
 907+ $didbegin = 0;
 908+ if ( $ignore ) {
 909+ if( !$this->mTrxLevel ) {
 910+ $this->begin();
 911+ $didbegin = 1;
 912+ }
 913+ $olde = error_reporting( 0 );
 914+ $numrowsinserted = 0;
 915+ pg_query( $this->mConn, "SAVEPOINT $ignore");
 916+ }
 917+
 918+ $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
 919+ " SELECT $startOpts " . implode( ',', $varMap ) .
 920+ " FROM $srcTable $useIndex";
 921+
 922+ if ( $conds != '*') {
 923+ $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
 924+ }
 925+
 926+ $sql .= " $tailOpts";
 927+
 928+ $res = (bool)$this->query( $sql, $fname, $ignore );
 929+ if( $ignore ) {
 930+ $bar = pg_last_error();
 931+ if( $bar != false ) {
 932+ pg_query( $this->mConn, "ROLLBACK TO $ignore" );
 933+ } else {
 934+ pg_query( $this->mConn, "RELEASE $ignore" );
 935+ $numrowsinserted++;
 936+ }
 937+ $olde = error_reporting( $olde );
 938+ if( $didbegin ) {
 939+ $this->commit();
 940+ }
 941+
 942+ // Set the affected row count for the whole operation
 943+ $this->mAffectedRows = $numrowsinserted;
 944+
 945+ // IGNORE always returns true
 946+ return true;
 947+ }
 948+
 949+ return $res;
 950+ }
 951+
877952 function tableName( $name ) {
878953 # Replace reserved words with better ones
879954 switch( $name ) {

Status & tagging log