Index: trunk/phase3/includes/db/DatabasePostgres.php |
— | — | @@ -16,8 +16,6 @@ |
17 | 17 | * @return null|PostgresField |
18 | 18 | */ |
19 | 19 | static function fromText( $db, $table, $field ) { |
20 | | - global $wgDBmwschema; |
21 | | - |
22 | 20 | $q = <<<SQL |
23 | 21 | SELECT |
24 | 22 | attnotnull, attlen, COALESCE(conname, '') AS conname, |
— | — | @@ -42,7 +40,7 @@ |
43 | 41 | $table = $db->tableName( $table, 'raw' ); |
44 | 42 | $res = $db->query( |
45 | 43 | sprintf( $q, |
46 | | - $db->addQuotes( $wgDBmwschema ), |
| 44 | + $db->addQuotes( $db->getCoreSchema() ), |
47 | 45 | $db->addQuotes( $table ), |
48 | 46 | $db->addQuotes( $field ) |
49 | 47 | ) |
— | — | @@ -98,8 +96,86 @@ |
99 | 97 | } |
100 | 98 | |
101 | 99 | /** |
| 100 | + * Used to debug transaction processing |
| 101 | + * Only used if $wgDebugDBTransactions is true |
| 102 | + * |
| 103 | + * @since 1.20 |
102 | 104 | * @ingroup Database |
103 | 105 | */ |
| 106 | +class PostgresTransactionState { |
| 107 | + |
| 108 | + static $WATCHED = array( |
| 109 | + array( |
| 110 | + "desc" => "Connection state changed from %s -> %s\n", |
| 111 | + "states" => array( |
| 112 | + PGSQL_CONNECTION_OK => "OK", |
| 113 | + PGSQL_CONNECTION_BAD => "BAD" |
| 114 | + ) |
| 115 | + ), |
| 116 | + array( |
| 117 | + "desc" => "Transaction state changed from %s -> %s\n", |
| 118 | + "states" => array( |
| 119 | + PGSQL_TRANSACTION_IDLE => "IDLE", |
| 120 | + PGSQL_TRANSACTION_ACTIVE => "ACTIVE", |
| 121 | + PGSQL_TRANSACTION_INTRANS => "TRANS", |
| 122 | + PGSQL_TRANSACTION_INERROR => "ERROR", |
| 123 | + PGSQL_TRANSACTION_UNKNOWN => "UNKNOWN" |
| 124 | + ) |
| 125 | + ) |
| 126 | + ); |
| 127 | + |
| 128 | + public function __construct( $conn ) { |
| 129 | + $this->mConn = $conn; |
| 130 | + $this->update(); |
| 131 | + $this->mCurrentState = $this->mNewState; |
| 132 | + } |
| 133 | + |
| 134 | + public function update() { |
| 135 | + $this->mNewState = array( |
| 136 | + pg_connection_status( $this->mConn ), |
| 137 | + pg_transaction_status( $this->mConn ) |
| 138 | + ); |
| 139 | + } |
| 140 | + |
| 141 | + public function check() { |
| 142 | + global $wgDebugDBTransactions; |
| 143 | + $this->update(); |
| 144 | + if ( $wgDebugDBTransactions ) { |
| 145 | + if ( $this->mCurrentState !== $this->mNewState ) { |
| 146 | + $old = reset( $this->mCurrentState ); |
| 147 | + $new = reset( $this->mNewState ); |
| 148 | + foreach ( self::$WATCHED as $watched ) { |
| 149 | + if ($old !== $new) { |
| 150 | + $this->log_changed($old, $new, $watched); |
| 151 | + } |
| 152 | + $old = next( $this->mCurrentState ); |
| 153 | + $new = next( $this->mNewState ); |
| 154 | + |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | + $this->mCurrentState = $this->mNewState; |
| 159 | + } |
| 160 | + |
| 161 | + protected function describe_changed( $status, $desc_table ) { |
| 162 | + if( isset( $desc_table[$status] ) ) { |
| 163 | + return $desc_table[$status]; |
| 164 | + } else { |
| 165 | + return "STATUS " . $status; |
| 166 | + } |
| 167 | + } |
| 168 | + |
| 169 | + protected function log_changed( $old, $new, $watched ) { |
| 170 | + wfDebug(sprintf($watched["desc"], |
| 171 | + $this->describe_changed( $old, $watched["states"] ), |
| 172 | + $this->describe_changed( $new, $watched["states"] )) |
| 173 | + ); |
| 174 | + } |
| 175 | +} |
| 176 | + |
| 177 | +/** |
| 178 | + * @ingroup Database |
| 179 | + */ |
104 | 180 | class DatabasePostgres extends DatabaseBase { |
105 | 181 | var $mInsertId = null; |
106 | 182 | var $mLastResult = null; |
— | — | @@ -136,9 +212,8 @@ |
137 | 213 | } |
138 | 214 | |
139 | 215 | function hasConstraint( $name ) { |
140 | | - global $wgDBmwschema; |
141 | 216 | $SQL = "SELECT 1 FROM pg_catalog.pg_constraint c, pg_catalog.pg_namespace n WHERE c.connamespace = n.oid AND conname = '" . |
142 | | - pg_escape_string( $this->mConn, $name ) . "' AND n.nspname = '" . pg_escape_string( $this->mConn, $wgDBmwschema ) ."'"; |
| 217 | + pg_escape_string( $this->mConn, $name ) . "' AND n.nspname = '" . pg_escape_string( $this->mConn, $this->mConn->getCoreSchema() ) ."'"; |
143 | 218 | $res = $this->doQuery( $SQL ); |
144 | 219 | return $this->numRows( $res ); |
145 | 220 | } |
— | — | @@ -177,10 +252,6 @@ |
178 | 253 | $connectVars['port'] = $port; |
179 | 254 | } |
180 | 255 | $this->connectString = $this->makeConnectionString( $connectVars, PGSQL_CONNECT_FORCE_NEW ); |
181 | | - $this->reOpen(); |
182 | | - } |
183 | | - |
184 | | - function reOpen() { |
185 | 256 | $this->close(); |
186 | 257 | $this->installErrorHandler(); |
187 | 258 | $this->mConn = pg_connect( $this->connectString ); |
— | — | @@ -194,6 +265,7 @@ |
195 | 266 | } |
196 | 267 | |
197 | 268 | $this->mOpened = true; |
| 269 | + $this->mTransactionState = new PostgresTransactionState( $this->mConn ); |
198 | 270 | |
199 | 271 | global $wgCommandLineMode; |
200 | 272 | # If called from the command-line (e.g. importDump), only show errors |
— | — | @@ -207,12 +279,7 @@ |
208 | 280 | $this->query( "SET standard_conforming_strings = on", __METHOD__ ); |
209 | 281 | |
210 | 282 | global $wgDBmwschema; |
211 | | - if ( $this->schemaExists( $wgDBmwschema ) ) { |
212 | | - $safeschema = $this->addIdentifierQuotes( $wgDBmwschema ); |
213 | | - $this->doQuery( "SET search_path = $safeschema" ); |
214 | | - } else { |
215 | | - $this->doQuery( "SET search_path = public" ); |
216 | | - } |
| 283 | + $this->determineCoreSchema( $wgDBmwschema ); |
217 | 284 | |
218 | 285 | return $this->mConn; |
219 | 286 | } |
— | — | @@ -248,17 +315,20 @@ |
249 | 316 | } |
250 | 317 | |
251 | 318 | protected function doQuery( $sql ) { |
| 319 | + global $wgDebugDBTransactions; |
252 | 320 | if ( function_exists( 'mb_convert_encoding' ) ) { |
253 | 321 | $sql = mb_convert_encoding( $sql, 'UTF-8' ); |
254 | 322 | } |
| 323 | + $this->mTransactionState->check(); |
255 | 324 | $this->mLastResult = pg_query( $this->mConn, $sql ); |
256 | | - $this->mAffectedRows = null; // use pg_affected_rows(mLastResult) |
| 325 | + $this->mTransactionState->check(); |
| 326 | + $this->mAffectedRows = null; |
257 | 327 | return $this->mLastResult; |
258 | 328 | } |
259 | 329 | |
260 | 330 | function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) { |
| 331 | + /* Transaction stays in the ERROR state until rolledback */ |
261 | 332 | $this->rollback( __METHOD__ ); |
262 | | - $this->reOpen(); |
263 | 333 | parent::reportQueryError( $error, $errno, $sql, $fname, $tempIgnore ); |
264 | 334 | } |
265 | 335 | |
— | — | @@ -502,7 +572,7 @@ |
503 | 573 | $tempsql .= '(' . $this->makeList( $row ) . ')'; |
504 | 574 | |
505 | 575 | if ( $ignore ) { |
506 | | - pg_query( $this->mConn, "SAVEPOINT $ignore" ); |
| 576 | + $this->doQuery( "SAVEPOINT $ignore" ); |
507 | 577 | } |
508 | 578 | |
509 | 579 | $tempres = (bool)$this->query( $tempsql, $fname, $ignore ); |
— | — | @@ -510,9 +580,9 @@ |
511 | 581 | if ( $ignore ) { |
512 | 582 | $bar = pg_last_error(); |
513 | 583 | if ( $bar != false ) { |
514 | | - pg_query( $this->mConn, "ROLLBACK TO $ignore" ); |
| 584 | + $this->doQuery( $this->mConn, "ROLLBACK TO $ignore" ); |
515 | 585 | } else { |
516 | | - pg_query( $this->mConn, "RELEASE $ignore" ); |
| 586 | + $this->doQuery( $this->mConn, "RELEASE $ignore" ); |
517 | 587 | $numrowsinserted++; |
518 | 588 | } |
519 | 589 | } |
— | — | @@ -527,7 +597,7 @@ |
528 | 598 | } else { |
529 | 599 | // Not multi, just a lone insert |
530 | 600 | if ( $ignore ) { |
531 | | - pg_query($this->mConn, "SAVEPOINT $ignore"); |
| 601 | + $this->doQuery( "SAVEPOINT $ignore" ); |
532 | 602 | } |
533 | 603 | |
534 | 604 | $sql .= '(' . $this->makeList( $args ) . ')'; |
— | — | @@ -535,9 +605,9 @@ |
536 | 606 | if ( $ignore ) { |
537 | 607 | $bar = pg_last_error(); |
538 | 608 | if ( $bar != false ) { |
539 | | - pg_query( $this->mConn, "ROLLBACK TO $ignore" ); |
| 609 | + $this->doQuery( "ROLLBACK TO $ignore" ); |
540 | 610 | } else { |
541 | | - pg_query( $this->mConn, "RELEASE $ignore" ); |
| 611 | + $this->doQuery( "RELEASE $ignore" ); |
542 | 612 | $numrowsinserted++; |
543 | 613 | } |
544 | 614 | } |
— | — | @@ -597,7 +667,7 @@ |
598 | 668 | } |
599 | 669 | $olde = error_reporting( 0 ); |
600 | 670 | $numrowsinserted = 0; |
601 | | - pg_query( $this->mConn, "SAVEPOINT $ignore"); |
| 671 | + $this->doQuery( "SAVEPOINT $ignore" ); |
602 | 672 | } |
603 | 673 | |
604 | 674 | $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' . |
— | — | @@ -614,9 +684,9 @@ |
615 | 685 | if( $ignore ) { |
616 | 686 | $bar = pg_last_error(); |
617 | 687 | if( $bar != false ) { |
618 | | - pg_query( $this->mConn, "ROLLBACK TO $ignore" ); |
| 688 | + $this->doQuery( "ROLLBACK TO $ignore" ); |
619 | 689 | } else { |
620 | | - pg_query( $this->mConn, "RELEASE $ignore" ); |
| 690 | + $this->doQuery( "RELEASE $ignore" ); |
621 | 691 | $numrowsinserted++; |
622 | 692 | } |
623 | 693 | $olde = error_reporting( $olde ); |
— | — | @@ -702,10 +772,8 @@ |
703 | 773 | } |
704 | 774 | |
705 | 775 | function listTables( $prefix = null, $fname = 'DatabasePostgres::listTables' ) { |
706 | | - global $wgDBmwschema; |
707 | | - $eschema = $this->addQuotes( $wgDBmwschema ); |
| 776 | + $eschema = $this->addQuotes( $this->getCoreSchema() ); |
708 | 777 | $result = $this->query( "SELECT tablename FROM pg_tables WHERE schemaname = $eschema", $fname ); |
709 | | - |
710 | 778 | $endArray = array(); |
711 | 779 | |
712 | 780 | foreach( $result as $table ) { |
— | — | @@ -723,6 +791,48 @@ |
724 | 792 | return wfTimestamp( TS_POSTGRES, $ts ); |
725 | 793 | } |
726 | 794 | |
| 795 | + |
| 796 | + /* |
| 797 | + * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12 |
| 798 | + * to http://www.php.net/manual/en/ref.pgsql.php |
| 799 | + * |
| 800 | + * Parsing a postgres array can be a tricky problem, he's my |
| 801 | + * take on this, it handles multi-dimensional arrays plus |
| 802 | + * escaping using a nasty regexp to determine the limits of each |
| 803 | + * data-item. |
| 804 | + * |
| 805 | + * This should really be handled by PHP PostgreSQL module |
| 806 | + * |
| 807 | + * @since 1.20 |
| 808 | + * @param text string: postgreql array returned in a text form like {a,b} |
| 809 | + * @param output string |
| 810 | + * @param limit int |
| 811 | + * @param offset int |
| 812 | + * @return string |
| 813 | + */ |
| 814 | + |
| 815 | + function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) { |
| 816 | + if( false === $limit ) { |
| 817 | + $limit = strlen( $text )-1; |
| 818 | + $output = array(); |
| 819 | + } |
| 820 | + if( '{}' != $text ) |
| 821 | + do { |
| 822 | + if ( '{' != $text{$offset} ) { |
| 823 | + preg_match( "/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/", |
| 824 | + $text, $match, 0, $offset ); |
| 825 | + $offset += strlen( $match[0] ); |
| 826 | + $output[] = ( '"' != $match[1]{0} |
| 827 | + ? $match[1] |
| 828 | + : stripcslashes( substr( $match[1], 1, -1 ) ) ); |
| 829 | + if ( '},' == $match[3] ) |
| 830 | + return $output; |
| 831 | + } else |
| 832 | + $offset = $this->pg_array_parse( $text, $output[], $limit, $offset+1 ); |
| 833 | + } while ( $limit > $offset ); |
| 834 | + return $output; |
| 835 | + } |
| 836 | + |
727 | 837 | /** |
728 | 838 | * Return aggregated value function call |
729 | 839 | */ |
— | — | @@ -737,7 +847,115 @@ |
738 | 848 | return '[http://www.postgresql.org/ PostgreSQL]'; |
739 | 849 | } |
740 | 850 | |
| 851 | + |
741 | 852 | /** |
| 853 | + * Return current schema (executes SELECT current_schema()) |
| 854 | + * Needs transaction |
| 855 | + * |
| 856 | + * @since 1.20 |
| 857 | + * @return string return default schema for the current session |
| 858 | + */ |
| 859 | + function getCurrentSchema() { |
| 860 | + $res = $this->query( "SELECT current_schema()", __METHOD__); |
| 861 | + $row = $this->fetchRow( $res ); |
| 862 | + return $row[0]; |
| 863 | + } |
| 864 | + |
| 865 | + /** |
| 866 | + * Return list of schemas which are accessible without schema name |
| 867 | + * This is list does not contain magic keywords like "$user" |
| 868 | + * Needs transaction |
| 869 | + * |
| 870 | + * @seealso getSearchPath() |
| 871 | + * @seealso setSearchPath() |
| 872 | + * @since 1.20 |
| 873 | + * @return array list of actual schemas for the current sesson |
| 874 | + */ |
| 875 | + function getSchemas() { |
| 876 | + $res = $this->query( "SELECT current_schemas(false)", __METHOD__); |
| 877 | + $row = $this->fetchRow( $res ); |
| 878 | + $schemas = array(); |
| 879 | + /* PHP pgsql support does not support array type, "{a,b}" string is returned */ |
| 880 | + return $this->pg_array_parse($row[0], $schemas); |
| 881 | + } |
| 882 | + |
| 883 | + /** |
| 884 | + * Return search patch for schemas |
| 885 | + * This is different from getSchemas() since it contain magic keywords |
| 886 | + * (like "$user"). |
| 887 | + * Needs transaction |
| 888 | + * |
| 889 | + * @since 1.20 |
| 890 | + * @return array how to search for table names schemas for the current user |
| 891 | + */ |
| 892 | + function getSearchPath() { |
| 893 | + $res = $this->query( "SHOW search_path", __METHOD__); |
| 894 | + $row = $this->fetchRow( $res ); |
| 895 | + /* PostgreSQL returns SHOW values as strings */ |
| 896 | + return explode(",", $row[0]); |
| 897 | + } |
| 898 | + |
| 899 | + function setSearchPath( $search_path ) { |
| 900 | + /** |
| 901 | + * Update search_path, values should already be sanitized |
| 902 | + * Values may contain magic keywords like "$user" |
| 903 | + * @since 1.20 |
| 904 | + * |
| 905 | + * @param array list of schemas to be searched by default |
| 906 | + */ |
| 907 | + $this->query( "SET search_path = " . implode(", ", $search_path) ); |
| 908 | + } |
| 909 | + |
| 910 | + /** |
| 911 | + * Determine default schema for MediaWiki core |
| 912 | + * Adjust this session schema search path if desired schema exists |
| 913 | + * and is not alread there. |
| 914 | + * |
| 915 | + * We need to have name of the core schema stored to be able |
| 916 | + * to query database metadata. |
| 917 | + * |
| 918 | + * This will be also called by the installer after the schema is created |
| 919 | + * |
| 920 | + * @since 1.20 |
| 921 | + * @param desired_schema string |
| 922 | + */ |
| 923 | + function determineCoreSchema( $desired_schema ) { |
| 924 | + $this->begin( __METHOD__ ); |
| 925 | + if ( $this->schemaExists( $desired_schema ) ) { |
| 926 | + if ( in_array( $desired_schema, $this->getSchemas() ) ) { |
| 927 | + $this->mCoreSchema = $desired_schema; |
| 928 | + wfDebug("Schema \"" . $desired_schema . "\" already in the search path\n"); |
| 929 | + } else { |
| 930 | + /** |
| 931 | + * Apped our schema (e.g. 'mediawiki') in front |
| 932 | + * of the search path |
| 933 | + * Fixes bug 15816 |
| 934 | + */ |
| 935 | + $search_path = $this->getSearchPath(); |
| 936 | + array_unshift( $search_path, |
| 937 | + $this->addIdentifierQuotes( $desired_schema )); |
| 938 | + $this->setSearchPath( $search_path ); |
| 939 | + wfDebug("Schema \"" . $desired_schema . "\" added to the search path\n"); |
| 940 | + } |
| 941 | + } else { |
| 942 | + $this->mCoreSchema = $this->getCurrentSchema(); |
| 943 | + wfDebug("Schema \"" . $desired_schema . "\" not found, using current \"". $this->mCoreSchema ."\"\n"); |
| 944 | + } |
| 945 | + /* Commit SET otherwise it will be rollbacked on error or IGNORE SELECT */ |
| 946 | + $this->commit( __METHOD__ ); |
| 947 | + } |
| 948 | + |
| 949 | + /** |
| 950 | + * Return schema name fore core MediaWiki tables |
| 951 | + * |
| 952 | + * @since 1.20 |
| 953 | + * @return string core schema name |
| 954 | + */ |
| 955 | + function getCoreSchema() { |
| 956 | + return $this->mCoreSchema; |
| 957 | + } |
| 958 | + |
| 959 | + /** |
742 | 960 | * @return string Version information from the database |
743 | 961 | */ |
744 | 962 | function getServerVersion() { |
— | — | @@ -763,12 +981,11 @@ |
764 | 982 | * @return bool |
765 | 983 | */ |
766 | 984 | function relationExists( $table, $types, $schema = false ) { |
767 | | - global $wgDBmwschema; |
768 | 985 | if ( !is_array( $types ) ) { |
769 | 986 | $types = array( $types ); |
770 | 987 | } |
771 | 988 | if ( !$schema ) { |
772 | | - $schema = $wgDBmwschema; |
| 989 | + $schema = $this->getCoreSchema(); |
773 | 990 | } |
774 | 991 | $table = $this->tableName( $table, 'raw' ); |
775 | 992 | $etable = $this->addQuotes( $table ); |
— | — | @@ -795,8 +1012,6 @@ |
796 | 1013 | } |
797 | 1014 | |
798 | 1015 | function triggerExists( $table, $trigger ) { |
799 | | - global $wgDBmwschema; |
800 | | - |
801 | 1016 | $q = <<<SQL |
802 | 1017 | SELECT 1 FROM pg_class, pg_namespace, pg_trigger |
803 | 1018 | WHERE relnamespace=pg_namespace.oid AND relkind='r' |
— | — | @@ -806,7 +1021,7 @@ |
807 | 1022 | $res = $this->query( |
808 | 1023 | sprintf( |
809 | 1024 | $q, |
810 | | - $this->addQuotes( $wgDBmwschema ), |
| 1025 | + $this->addQuotes( $this->getCoreSchema() ), |
811 | 1026 | $this->addQuotes( $table ), |
812 | 1027 | $this->addQuotes( $trigger ) |
813 | 1028 | ) |
— | — | @@ -819,22 +1034,20 @@ |
820 | 1035 | } |
821 | 1036 | |
822 | 1037 | function ruleExists( $table, $rule ) { |
823 | | - global $wgDBmwschema; |
824 | 1038 | $exists = $this->selectField( 'pg_rules', 'rulename', |
825 | 1039 | array( |
826 | 1040 | 'rulename' => $rule, |
827 | 1041 | 'tablename' => $table, |
828 | | - 'schemaname' => $wgDBmwschema |
| 1042 | + 'schemaname' => $this->getCoreSchema() |
829 | 1043 | ) |
830 | 1044 | ); |
831 | 1045 | return $exists === $rule; |
832 | 1046 | } |
833 | 1047 | |
834 | 1048 | function constraintExists( $table, $constraint ) { |
835 | | - global $wgDBmwschema; |
836 | 1049 | $SQL = sprintf( "SELECT 1 FROM information_schema.table_constraints ". |
837 | 1050 | "WHERE constraint_schema = %s AND table_name = %s AND constraint_name = %s", |
838 | | - $this->addQuotes( $wgDBmwschema ), |
| 1051 | + $this->addQuotes( $this->getCoreSchema() ), |
839 | 1052 | $this->addQuotes( $table ), |
840 | 1053 | $this->addQuotes( $constraint ) |
841 | 1054 | ); |
Index: trunk/phase3/includes/db/Database.php |
— | — | @@ -784,7 +784,7 @@ |
785 | 785 | * @return bool |
786 | 786 | */ |
787 | 787 | function isWriteQuery( $sql ) { |
788 | | - return !preg_match( '/^(?:SELECT|BEGIN|COMMIT|SET|SHOW|\(SELECT)\b/i', $sql ); |
| 788 | + return !preg_match( '/^(?:SELECT|BEGIN|ROLLBACK|COMMIT|SET|SHOW|\(SELECT)\b/i', $sql ); |
789 | 789 | } |
790 | 790 | |
791 | 791 | /** |
Index: trunk/phase3/includes/installer/PostgresUpdater.php |
— | — | @@ -270,7 +270,6 @@ |
271 | 271 | } |
272 | 272 | |
273 | 273 | protected function describeTable( $table ) { |
274 | | - global $wgDBmwschema; |
275 | 274 | $q = <<<END |
276 | 275 | SELECT attname, attnum FROM pg_namespace, pg_class, pg_attribute |
277 | 276 | WHERE pg_class.relnamespace = pg_namespace.oid |
— | — | @@ -279,7 +278,7 @@ |
280 | 279 | END; |
281 | 280 | $res = $this->db->query( sprintf( $q, |
282 | 281 | $this->db->addQuotes( $table ), |
283 | | - $this->db->addQuotes( $wgDBmwschema ) ) ); |
| 282 | + $this->db->addQuotes( $this->db->getCoreSchema() ) ) ); |
284 | 283 | if ( !$res ) { |
285 | 284 | return null; |
286 | 285 | } |
— | — | @@ -295,8 +294,6 @@ |
296 | 295 | } |
297 | 296 | |
298 | 297 | function describeIndex( $idx ) { |
299 | | - global $wgDBmwschema; |
300 | | - |
301 | 298 | // first fetch the key (which is a list of columns ords) and |
302 | 299 | // the table the index applies to (an oid) |
303 | 300 | $q = <<<END |
— | — | @@ -309,7 +306,7 @@ |
310 | 307 | $res = $this->db->query( |
311 | 308 | sprintf( |
312 | 309 | $q, |
313 | | - $this->db->addQuotes( $wgDBmwschema ), |
| 310 | + $this->db->addQuotes( $this->db->getCoreSchea() ), |
314 | 311 | $this->db->addQuotes( $idx ) |
315 | 312 | ) |
316 | 313 | ); |
— | — | @@ -346,7 +343,6 @@ |
347 | 344 | } |
348 | 345 | |
349 | 346 | function fkeyDeltype( $fkey ) { |
350 | | - global $wgDBmwschema; |
351 | 347 | $q = <<<END |
352 | 348 | SELECT confdeltype FROM pg_constraint, pg_namespace |
353 | 349 | WHERE connamespace=pg_namespace.oid |
— | — | @@ -356,7 +352,7 @@ |
357 | 353 | $r = $this->db->query( |
358 | 354 | sprintf( |
359 | 355 | $q, |
360 | | - $this->db->addQuotes( $wgDBmwschema ), |
| 356 | + $this->db->addQuotes( $this->db->getCoreSchema() ), |
361 | 357 | $this->db->addQuotes( $fkey ) |
362 | 358 | ) |
363 | 359 | ); |
— | — | @@ -367,7 +363,6 @@ |
368 | 364 | } |
369 | 365 | |
370 | 366 | function ruleDef( $table, $rule ) { |
371 | | - global $wgDBmwschema; |
372 | 367 | $q = <<<END |
373 | 368 | SELECT definition FROM pg_rules |
374 | 369 | WHERE schemaname = %s |
— | — | @@ -377,7 +372,7 @@ |
378 | 373 | $r = $this->db->query( |
379 | 374 | sprintf( |
380 | 375 | $q, |
381 | | - $this->db->addQuotes( $wgDBmwschema ), |
| 376 | + $this->db->addQuotes( $this->db->getCoreSchema() ), |
382 | 377 | $this->db->addQuotes( $table ), |
383 | 378 | $this->db->addQuotes( $rule ) |
384 | 379 | ) |
Index: trunk/phase3/includes/installer/PostgresInstaller.php |
— | — | @@ -431,10 +431,6 @@ |
432 | 432 | $conn = $status->value; |
433 | 433 | |
434 | 434 | $dbName = $this->getVar( 'wgDBname' ); |
435 | | - //$schema = $this->getVar( 'wgDBmwschema' ); |
436 | | - //$user = $this->getVar( 'wgDBuser' ); |
437 | | - //$safeschema = $conn->addIdentifierQuotes( $schema ); |
438 | | - //$safeuser = $conn->addIdentifierQuotes( $user ); |
439 | 435 | |
440 | 436 | $exists = $conn->selectField( '"pg_catalog"."pg_database"', '1', |
441 | 437 | array( 'datname' => $dbName ), __METHOD__ ); |
— | — | @@ -466,14 +462,8 @@ |
467 | 463 | } |
468 | 464 | } |
469 | 465 | |
470 | | - // If we created a user, alter it now to search the new schema by default |
471 | | - if ( $this->getVar( '_CreateDBAccount' ) ) { |
472 | | - $conn->query( "ALTER ROLE $safeuser SET search_path = $safeschema, public", |
473 | | - __METHOD__ ); |
474 | | - } |
475 | | - |
476 | 466 | // Select the new schema in the current connection |
477 | | - $conn->query( "SET search_path = $safeschema" ); |
| 467 | + $conn->determineCoreSchema( $schema ); |
478 | 468 | return Status::newGood(); |
479 | 469 | } |
480 | 470 | |
— | — | @@ -493,10 +483,8 @@ |
494 | 484 | } |
495 | 485 | $conn = $status->value; |
496 | 486 | |
497 | | - //$schema = $this->getVar( 'wgDBmwschema' ); |
498 | 487 | $safeuser = $conn->addIdentifierQuotes( $this->getVar( 'wgDBuser' ) ); |
499 | 488 | $safepass = $conn->addQuotes( $this->getVar( 'wgDBpassword' ) ); |
500 | | - //$safeschema = $conn->addIdentifierQuotes( $schema ); |
501 | 489 | |
502 | 490 | // Check if the user already exists |
503 | 491 | $userExists = $conn->roleExists( $this->getVar( 'wgDBuser' ) ); |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -4060,6 +4060,11 @@ |
4061 | 4061 | $wgDebugComments = false; |
4062 | 4062 | |
4063 | 4063 | /** |
| 4064 | + * Extensive database transaction state debugging |
| 4065 | + */ |
| 4066 | +$wgDebugDBTransactions = false; |
| 4067 | + |
| 4068 | +/** |
4064 | 4069 | * Write SQL queries to the debug log |
4065 | 4070 | */ |
4066 | 4071 | $wgDebugDumpSql = false; |
Index: trunk/phase3/RELEASE-NOTES-1.20 |
— | — | @@ -22,6 +22,7 @@ |
23 | 23 | * (bug 27619) Remove preference option to display broken links as link? |
24 | 24 | * (bug 34896) Update jQuery JSON plugin to v2.3 (2011-09-17) |
25 | 25 | * (bug 34302) Add CSS classes to email fields in user preferences |
| 26 | +* Introduced $wgDebugDBTransactions to trace transaction status (currently PostgreSQL only) |
26 | 27 | |
27 | 28 | === Bug fixes in 1.20 === |
28 | 29 | * (bug 30245) Use the correct way to construct a log page title. |
— | — | @@ -42,6 +43,7 @@ |
43 | 44 | Special:MyPage and Special:MyTalk |
44 | 45 | * (bug 34929) Show the correct diff when a section edit is rejected by the spam |
45 | 46 | filter |
| 47 | +* (bug 15816) Add a switch for SETting the search_path (Postgres) |
46 | 48 | |
47 | 49 | === API changes in 1.20 === |
48 | 50 | * (bug 34316) Add ability to retrieve maximum upload size from MediaWiki API. |