MediaWiki  1.23.8
DatabasePostgres.php
Go to the documentation of this file.
1 <?php
24 class PostgresField implements Field {
27 
34  static function fromText( $db, $table, $field ) {
35  $q = <<<SQL
36 SELECT
37  attnotnull, attlen, conname AS conname,
38  atthasdef,
39  adsrc,
40  COALESCE(condeferred, 'f') AS deferred,
41  COALESCE(condeferrable, 'f') AS deferrable,
42  CASE WHEN typname = 'int2' THEN 'smallint'
43  WHEN typname = 'int4' THEN 'integer'
44  WHEN typname = 'int8' THEN 'bigint'
45  WHEN typname = 'bpchar' THEN 'char'
46  ELSE typname END AS typname
47 FROM pg_class c
48 JOIN pg_namespace n ON (n.oid = c.relnamespace)
49 JOIN pg_attribute a ON (a.attrelid = c.oid)
50 JOIN pg_type t ON (t.oid = a.atttypid)
51 LEFT JOIN pg_constraint o ON (o.conrelid = c.oid AND a.attnum = ANY(o.conkey) AND o.contype = 'f')
52 LEFT JOIN pg_attrdef d on c.oid=d.adrelid and a.attnum=d.adnum
53 WHERE relkind = 'r'
54 AND nspname=%s
55 AND relname=%s
56 AND attname=%s;
57 SQL;
58 
59  $table = $db->tableName( $table, 'raw' );
60  $res = $db->query(
61  sprintf( $q,
62  $db->addQuotes( $db->getCoreSchema() ),
63  $db->addQuotes( $table ),
64  $db->addQuotes( $field )
65  )
66  );
67  $row = $db->fetchObject( $res );
68  if ( !$row ) {
69  return null;
70  }
71  $n = new PostgresField;
72  $n->type = $row->typname;
73  $n->nullable = ( $row->attnotnull == 'f' );
74  $n->name = $field;
75  $n->tablename = $table;
76  $n->max_length = $row->attlen;
77  $n->deferrable = ( $row->deferrable == 't' );
78  $n->deferred = ( $row->deferred == 't' );
79  $n->conname = $row->conname;
80  $n->has_default = ( $row->atthasdef === 't' );
81  $n->default = $row->adsrc;
82 
83  return $n;
84  }
85 
86  function name() {
87  return $this->name;
88  }
89 
90  function tableName() {
91  return $this->tablename;
92  }
93 
94  function type() {
95  return $this->type;
96  }
97 
98  function isNullable() {
99  return $this->nullable;
100  }
101 
102  function maxLength() {
103  return $this->max_length;
104  }
105 
106  function is_deferrable() {
107  return $this->deferrable;
108  }
109 
110  function is_deferred() {
111  return $this->deferred;
112  }
113 
114  function conname() {
116  }
117 
121  function defaultValue() {
122  if ( $this->has_default ) {
123  return $this->default;
124  } else {
125  return false;
126  }
127  }
128 }
129 
138  private static $WATCHED = array(
139  array(
140  "desc" => "%s: Connection state changed from %s -> %s\n",
141  "states" => array(
142  PGSQL_CONNECTION_OK => "OK",
143  PGSQL_CONNECTION_BAD => "BAD"
144  )
145  ),
147  "desc" => "%s: Transaction state changed from %s -> %s\n",
148  "states" => array(
149  PGSQL_TRANSACTION_IDLE => "IDLE",
150  PGSQL_TRANSACTION_ACTIVE => "ACTIVE",
151  PGSQL_TRANSACTION_INTRANS => "TRANS",
152  PGSQL_TRANSACTION_INERROR => "ERROR",
153  PGSQL_TRANSACTION_UNKNOWN => "UNKNOWN"
154  )
155  )
156  );
157 
159  private $mNewState;
160 
162  private $mCurrentState;
163 
164  public function __construct( $conn ) {
165  $this->mConn = $conn;
166  $this->update();
167  $this->mCurrentState = $this->mNewState;
168  }
169 
170  public function update() {
171  $this->mNewState = array(
172  pg_connection_status( $this->mConn ),
173  pg_transaction_status( $this->mConn )
174  );
175  }
176 
177  public function check() {
178  global $wgDebugDBTransactions;
179  $this->update();
180  if ( $wgDebugDBTransactions ) {
181  if ( $this->mCurrentState !== $this->mNewState ) {
182  $old = reset( $this->mCurrentState );
183  $new = reset( $this->mNewState );
184  foreach ( self::$WATCHED as $watched ) {
185  if ( $old !== $new ) {
186  $this->log_changed( $old, $new, $watched );
187  }
188  $old = next( $this->mCurrentState );
189  $new = next( $this->mNewState );
190  }
191  }
192  }
193  $this->mCurrentState = $this->mNewState;
194  }
195 
196  protected function describe_changed( $status, $desc_table ) {
197  if ( isset( $desc_table[$status] ) ) {
198  return $desc_table[$status];
199  } else {
200  return "STATUS " . $status;
201  }
202  }
203 
204  protected function log_changed( $old, $new, $watched ) {
205  wfDebug( sprintf( $watched["desc"],
206  $this->mConn,
207  $this->describe_changed( $old, $watched["states"] ),
208  $this->describe_changed( $new, $watched["states"] )
209  ) );
210  }
211 }
212 
218 class SavepointPostgres {
220  protected $dbw;
221  protected $id;
222  protected $didbegin;
223 
228  public function __construct( $dbw, $id ) {
229  $this->dbw = $dbw;
230  $this->id = $id;
231  $this->didbegin = false;
232  /* If we are not in a transaction, we need to be for savepoint trickery */
233  if ( !$dbw->trxLevel() ) {
234  $dbw->begin( "FOR SAVEPOINT" );
235  $this->didbegin = true;
236  }
237  }
238 
239  public function __destruct() {
240  if ( $this->didbegin ) {
241  $this->dbw->rollback();
242  $this->didbegin = false;
243  }
244  }
245 
246  public function commit() {
247  if ( $this->didbegin ) {
248  $this->dbw->commit();
249  $this->didbegin = false;
250  }
251  }
252 
253  protected function query( $keyword, $msg_ok, $msg_failed ) {
254  global $wgDebugDBTransactions;
255  if ( $this->dbw->doQuery( $keyword . " " . $this->id ) !== false ) {
256  if ( $wgDebugDBTransactions ) {
257  wfDebug( sprintf( $msg_ok, $this->id ) );
258  }
259  } else {
260  wfDebug( sprintf( $msg_failed, $this->id ) );
261  }
262  }
263 
264  public function savepoint() {
265  $this->query( "SAVEPOINT",
266  "Transaction state: savepoint \"%s\" established.\n",
267  "Transaction state: establishment of savepoint \"%s\" FAILED.\n"
268  );
269  }
270 
271  public function release() {
272  $this->query( "RELEASE",
273  "Transaction state: savepoint \"%s\" released.\n",
274  "Transaction state: release of savepoint \"%s\" FAILED.\n"
275  );
276  }
277 
278  public function rollback() {
279  $this->query( "ROLLBACK TO",
280  "Transaction state: savepoint \"%s\" rolled back.\n",
281  "Transaction state: rollback of savepoint \"%s\" FAILED.\n"
282  );
283  }
284 
285  public function __toString() {
286  return (string)$this->id;
287  }
288 }
289 
293 class DatabasePostgres extends DatabaseBase {
295  protected $mLastResult = null;
296 
298  protected $mAffectedRows = null;
299 
301  private $mInsertId = null;
302 
304  private $numericVersion = null;
305 
307  private $connectString;
308 
310  private $mTransactionState;
311 
313  private $mCoreSchema;
314 
315  function getType() {
316  return 'postgres';
317  }
318 
319  function cascadingDeletes() {
320  return true;
321  }
322 
323  function cleanupTriggers() {
324  return true;
325  }
326 
327  function strictIPs() {
328  return true;
329  }
330 
331  function realTimestamps() {
332  return true;
333  }
334 
335  function implicitGroupby() {
336  return false;
337  }
338 
339  function implicitOrderby() {
340  return false;
341  }
342 
343  function searchableIPs() {
344  return true;
345  }
346 
347  function functionalIndexes() {
348  return true;
349  }
350 
351  function hasConstraint( $name ) {
352  $sql = "SELECT 1 FROM pg_catalog.pg_constraint c, pg_catalog.pg_namespace n " .
353  "WHERE c.connamespace = n.oid AND conname = '" .
354  pg_escape_string( $this->mConn, $name ) . "' AND n.nspname = '" .
355  pg_escape_string( $this->mConn, $this->getCoreSchema() ) . "'";
356  $res = $this->doQuery( $sql );
357 
358  return $this->numRows( $res );
359  }
360 
370  function open( $server, $user, $password, $dbName ) {
371  # Test for Postgres support, to avoid suppressed fatal error
372  if ( !function_exists( 'pg_connect' ) ) {
373  throw new DBConnectionError(
374  $this,
375  "Postgres functions missing, have you compiled PHP with the --with-pgsql\n" .
376  "option? (Note: if you recently installed PHP, you may need to restart your\n" .
377  "webserver and database)\n"
378  );
379  }
380 
381  global $wgDBport;
382 
383  if ( !strlen( $user ) ) { # e.g. the class is being loaded
384  return null;
385  }
386 
387  $this->mServer = $server;
388  $port = $wgDBport;
389  $this->mUser = $user;
390  $this->mPassword = $password;
391  $this->mDBname = $dbName;
392 
393  $connectVars = array(
394  'dbname' => $dbName,
395  'user' => $user,
396  'password' => $password
397  );
398  if ( $server != false && $server != '' ) {
399  $connectVars['host'] = $server;
400  }
401  if ( $port != false && $port != '' ) {
402  $connectVars['port'] = $port;
403  }
404  if ( $this->mFlags & DBO_SSL ) {
405  $connectVars['sslmode'] = 1;
406  }
407 
408  $this->connectString = $this->makeConnectionString( $connectVars, PGSQL_CONNECT_FORCE_NEW );
409  $this->close();
410  $this->installErrorHandler();
411 
412  try {
413  $this->mConn = pg_connect( $this->connectString );
414  } catch ( Exception $ex ) {
415  $this->restoreErrorHandler();
416  throw $ex;
417  }
418 
419  $phpError = $this->restoreErrorHandler();
420 
421  if ( !$this->mConn ) {
422  wfDebug( "DB connection error\n" );
423  wfDebug( "Server: $server, Database: $dbName, User: $user, Password: " .
424  substr( $password, 0, 3 ) . "...\n" );
425  wfDebug( $this->lastError() . "\n" );
426  throw new DBConnectionError( $this, str_replace( "\n", ' ', $phpError ) );
427  }
428 
429  $this->mOpened = true;
430  $this->mTransactionState = new PostgresTransactionState( $this->mConn );
431 
433  # If called from the command-line (e.g. importDump), only show errors
435  $this->doQuery( "SET client_min_messages = 'ERROR'" );
436  }
437 
438  $this->query( "SET client_encoding='UTF8'", __METHOD__ );
439  $this->query( "SET datestyle = 'ISO, YMD'", __METHOD__ );
440  $this->query( "SET timezone = 'GMT'", __METHOD__ );
441  $this->query( "SET standard_conforming_strings = on", __METHOD__ );
442  if ( $this->getServerVersion() >= 9.0 ) {
443  $this->query( "SET bytea_output = 'escape'", __METHOD__ ); // PHP bug 53127
444  }
445 
446  global $wgDBmwschema;
447  $this->determineCoreSchema( $wgDBmwschema );
448 
449  return $this->mConn;
450  }
451 
458  function selectDB( $db ) {
459  if ( $this->mDBname !== $db ) {
460  return (bool)$this->open( $this->mServer, $this->mUser, $this->mPassword, $db );
461  } else {
462  return true;
463  }
464  }
465 
466  function makeConnectionString( $vars ) {
467  $s = '';
468  foreach ( $vars as $name => $value ) {
469  $s .= "$name='" . str_replace( "'", "\\'", $value ) . "' ";
470  }
471 
472  return $s;
473  }
474 
480  protected function closeConnection() {
481  return pg_close( $this->mConn );
482  }
483 
484  public function doQuery( $sql ) {
485  if ( function_exists( 'mb_convert_encoding' ) ) {
486  $sql = mb_convert_encoding( $sql, 'UTF-8' );
487  }
488  $this->mTransactionState->check();
489  if ( pg_send_query( $this->mConn, $sql ) === false ) {
490  throw new DBUnexpectedError( $this, "Unable to post new query to PostgreSQL\n" );
491  }
492  $this->mLastResult = pg_get_result( $this->mConn );
493  $this->mTransactionState->check();
494  $this->mAffectedRows = null;
495  if ( pg_result_error( $this->mLastResult ) ) {
496  return false;
497  }
498 
499  return $this->mLastResult;
500  }
501 
502  protected function dumpError() {
503  $diags = array(
504  PGSQL_DIAG_SEVERITY,
505  PGSQL_DIAG_SQLSTATE,
506  PGSQL_DIAG_MESSAGE_PRIMARY,
507  PGSQL_DIAG_MESSAGE_DETAIL,
508  PGSQL_DIAG_MESSAGE_HINT,
509  PGSQL_DIAG_STATEMENT_POSITION,
510  PGSQL_DIAG_INTERNAL_POSITION,
511  PGSQL_DIAG_INTERNAL_QUERY,
512  PGSQL_DIAG_CONTEXT,
513  PGSQL_DIAG_SOURCE_FILE,
514  PGSQL_DIAG_SOURCE_LINE,
515  PGSQL_DIAG_SOURCE_FUNCTION
516  );
517  foreach ( $diags as $d ) {
518  wfDebug( sprintf( "PgSQL ERROR(%d): %s\n",
519  $d, pg_result_error_field( $this->mLastResult, $d ) ) );
520  }
521  }
522 
523  function reportQueryError( $error, $errno, $sql, $fname, $tempIgnore = false ) {
524  /* Transaction stays in the ERROR state until rolledback */
525  if ( $tempIgnore ) {
526  /* Check for constraint violation */
527  if ( $errno === '23505' ) {
528  parent::reportQueryError( $error, $errno, $sql, $fname, $tempIgnore );
529 
530  return;
531  }
532  }
533  /* Don't ignore serious errors */
534  $this->rollback( __METHOD__ );
535  parent::reportQueryError( $error, $errno, $sql, $fname, false );
536  }
537 
538  function queryIgnore( $sql, $fname = __METHOD__ ) {
539  return $this->query( $sql, $fname, true );
540  }
541 
546  function freeResult( $res ) {
547  if ( $res instanceof ResultWrapper ) {
548  $res = $res->result;
549  }
551  $ok = pg_free_result( $res );
553  if ( !$ok ) {
554  throw new DBUnexpectedError( $this, "Unable to free Postgres result\n" );
555  }
556  }
557 
563  function fetchObject( $res ) {
564  if ( $res instanceof ResultWrapper ) {
565  $res = $res->result;
566  }
568  $row = pg_fetch_object( $res );
570  # @todo FIXME: HACK HACK HACK HACK debug
571 
572  # @todo hashar: not sure if the following test really trigger if the object
573  # fetching failed.
574  if ( pg_last_error( $this->mConn ) ) {
575  throw new DBUnexpectedError(
576  $this,
577  'SQL error: ' . htmlspecialchars( pg_last_error( $this->mConn ) )
578  );
579  }
580 
581  return $row;
582  }
583 
584  function fetchRow( $res ) {
585  if ( $res instanceof ResultWrapper ) {
586  $res = $res->result;
587  }
589  $row = pg_fetch_array( $res );
591  if ( pg_last_error( $this->mConn ) ) {
592  throw new DBUnexpectedError(
593  $this,
594  'SQL error: ' . htmlspecialchars( pg_last_error( $this->mConn ) )
595  );
596  }
597 
598  return $row;
599  }
600 
601  function numRows( $res ) {
602  if ( $res instanceof ResultWrapper ) {
603  $res = $res->result;
604  }
606  $n = pg_num_rows( $res );
608  if ( pg_last_error( $this->mConn ) ) {
609  throw new DBUnexpectedError(
610  $this,
611  'SQL error: ' . htmlspecialchars( pg_last_error( $this->mConn ) )
612  );
613  }
614 
615  return $n;
616  }
617 
618  function numFields( $res ) {
619  if ( $res instanceof ResultWrapper ) {
620  $res = $res->result;
621  }
622 
623  return pg_num_fields( $res );
624  }
625 
626  function fieldName( $res, $n ) {
627  if ( $res instanceof ResultWrapper ) {
628  $res = $res->result;
629  }
630 
631  return pg_field_name( $res, $n );
632  }
633 
640  function insertId() {
641  return $this->mInsertId;
642  }
643 
649  function dataSeek( $res, $row ) {
650  if ( $res instanceof ResultWrapper ) {
651  $res = $res->result;
652  }
653 
654  return pg_result_seek( $res, $row );
655  }
656 
657  function lastError() {
658  if ( $this->mConn ) {
659  if ( $this->mLastResult ) {
660  return pg_result_error( $this->mLastResult );
661  } else {
662  return pg_last_error();
663  }
664  } else {
665  return 'No database connection';
666  }
667  }
668 
669  function lastErrno() {
670  if ( $this->mLastResult ) {
671  return pg_result_error_field( $this->mLastResult, PGSQL_DIAG_SQLSTATE );
672  } else {
673  return false;
674  }
675  }
676 
677  function affectedRows() {
678  if ( !is_null( $this->mAffectedRows ) ) {
679  // Forced result for simulated queries
680  return $this->mAffectedRows;
681  }
682  if ( empty( $this->mLastResult ) ) {
683  return 0;
684  }
685 
686  return pg_affected_rows( $this->mLastResult );
687  }
688 
703  function estimateRowCount( $table, $vars = '*', $conds = '',
704  $fname = __METHOD__, $options = array()
705  ) {
706  $options['EXPLAIN'] = true;
707  $res = $this->select( $table, $vars, $conds, $fname, $options );
708  $rows = -1;
709  if ( $res ) {
710  $row = $this->fetchRow( $res );
711  $count = array();
712  if ( preg_match( '/rows=(\d+)/', $row[0], $count ) ) {
713  $rows = $count[1];
714  }
715  }
716 
717  return $rows;
718  }
719 
729  function indexInfo( $table, $index, $fname = __METHOD__ ) {
730  $sql = "SELECT indexname FROM pg_indexes WHERE tablename='$table'";
731  $res = $this->query( $sql, $fname );
732  if ( !$res ) {
733  return null;
734  }
735  foreach ( $res as $row ) {
736  if ( $row->indexname == $this->indexName( $index ) ) {
737  return $row;
738  }
739  }
740 
741  return false;
742  }
743 
752  function indexAttributes( $index, $schema = false ) {
753  if ( $schema === false ) {
754  $schema = $this->getCoreSchema();
755  }
756  /*
757  * A subquery would be not needed if we didn't care about the order
758  * of attributes, but we do
759  */
760  $sql = <<<__INDEXATTR__
761 
762  SELECT opcname,
763  attname,
764  i.indoption[s.g] as option,
765  pg_am.amname
766  FROM
767  (SELECT generate_series(array_lower(isub.indkey,1), array_upper(isub.indkey,1)) AS g
768  FROM
769  pg_index isub
770  JOIN pg_class cis
771  ON cis.oid=isub.indexrelid
772  JOIN pg_namespace ns
773  ON cis.relnamespace = ns.oid
774  WHERE cis.relname='$index' AND ns.nspname='$schema') AS s,
775  pg_attribute,
776  pg_opclass opcls,
777  pg_am,
778  pg_class ci
779  JOIN pg_index i
780  ON ci.oid=i.indexrelid
781  JOIN pg_class ct
782  ON ct.oid = i.indrelid
783  JOIN pg_namespace n
784  ON ci.relnamespace = n.oid
785  WHERE
786  ci.relname='$index' AND n.nspname='$schema'
787  AND attrelid = ct.oid
788  AND i.indkey[s.g] = attnum
789  AND i.indclass[s.g] = opcls.oid
790  AND pg_am.oid = opcls.opcmethod
791 __INDEXATTR__;
792  $res = $this->query( $sql, __METHOD__ );
793  $a = array();
794  if ( $res ) {
795  foreach ( $res as $row ) {
796  $a[] = array(
797  $row->attname,
798  $row->opcname,
799  $row->amname,
800  $row->option );
801  }
802  } else {
803  return null;
804  }
805 
806  return $a;
807  }
808 
809  function indexUnique( $table, $index, $fname = __METHOD__ ) {
810  $sql = "SELECT indexname FROM pg_indexes WHERE tablename='{$table}'" .
811  " AND indexdef LIKE 'CREATE UNIQUE%(" .
812  $this->strencode( $this->indexName( $index ) ) .
813  ")'";
814  $res = $this->query( $sql, $fname );
815  if ( !$res ) {
816  return null;
817  }
818 
819  return $res->numRows() > 0;
820  }
821 
832  function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
833  $options = array(), $join_conds = array()
834  ) {
835  if ( is_array( $options ) ) {
836  $forUpdateKey = array_search( 'FOR UPDATE', $options );
837  if ( $forUpdateKey !== false && $join_conds ) {
838  unset( $options[$forUpdateKey] );
839 
840  foreach ( $join_conds as $table_cond => $join_cond ) {
841  if ( 0 === preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0] ) ) {
842  $options['FOR UPDATE'][] = $table_cond;
843  }
844  }
845  }
846 
847  if ( isset( $options['ORDER BY'] ) && $options['ORDER BY'] == 'NULL' ) {
848  unset( $options['ORDER BY'] );
849  }
850  }
851 
852  return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
853  }
854 
867  function insert( $table, $args, $fname = __METHOD__, $options = array() ) {
868  if ( !count( $args ) ) {
869  return true;
870  }
871 
872  $table = $this->tableName( $table );
873  if ( !isset( $this->numericVersion ) ) {
874  $this->getServerVersion();
875  }
876 
877  if ( !is_array( $options ) ) {
878  $options = array( $options );
879  }
880 
881  if ( isset( $args[0] ) && is_array( $args[0] ) ) {
882  $multi = true;
883  $keys = array_keys( $args[0] );
884  } else {
885  $multi = false;
886  $keys = array_keys( $args );
887  }
888 
889  // If IGNORE is set, we use savepoints to emulate mysql's behavior
890  $savepoint = null;
891  if ( in_array( 'IGNORE', $options ) ) {
892  $savepoint = new SavepointPostgres( $this, 'mw' );
893  $olde = error_reporting( 0 );
894  // For future use, we may want to track the number of actual inserts
895  // Right now, insert (all writes) simply return true/false
896  $numrowsinserted = 0;
897  }
898 
899  $sql = "INSERT INTO $table (" . implode( ',', $keys ) . ') VALUES ';
900 
901  if ( $multi ) {
902  if ( $this->numericVersion >= 8.2 && !$savepoint ) {
903  $first = true;
904  foreach ( $args as $row ) {
905  if ( $first ) {
906  $first = false;
907  } else {
908  $sql .= ',';
909  }
910  $sql .= '(' . $this->makeList( $row ) . ')';
911  }
912  $res = (bool)$this->query( $sql, $fname, $savepoint );
913  } else {
914  $res = true;
915  $origsql = $sql;
916  foreach ( $args as $row ) {
917  $tempsql = $origsql;
918  $tempsql .= '(' . $this->makeList( $row ) . ')';
919 
920  if ( $savepoint ) {
921  $savepoint->savepoint();
922  }
923 
924  $tempres = (bool)$this->query( $tempsql, $fname, $savepoint );
925 
926  if ( $savepoint ) {
927  $bar = pg_last_error();
928  if ( $bar != false ) {
929  $savepoint->rollback();
930  } else {
931  $savepoint->release();
932  $numrowsinserted++;
933  }
934  }
935 
936  // If any of them fail, we fail overall for this function call
937  // Note that this will be ignored if IGNORE is set
938  if ( !$tempres ) {
939  $res = false;
940  }
941  }
942  }
943  } else {
944  // Not multi, just a lone insert
945  if ( $savepoint ) {
946  $savepoint->savepoint();
947  }
948 
949  $sql .= '(' . $this->makeList( $args ) . ')';
950  $res = (bool)$this->query( $sql, $fname, $savepoint );
951  if ( $savepoint ) {
952  $bar = pg_last_error();
953  if ( $bar != false ) {
954  $savepoint->rollback();
955  } else {
956  $savepoint->release();
957  $numrowsinserted++;
958  }
959  }
960  }
961  if ( $savepoint ) {
962  error_reporting( $olde );
963  $savepoint->commit();
964 
965  // Set the affected row count for the whole operation
966  $this->mAffectedRows = $numrowsinserted;
967 
968  // IGNORE always returns true
969  return true;
970  }
971 
972  return $res;
973  }
974 
993  function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
994  $insertOptions = array(), $selectOptions = array() ) {
995  $destTable = $this->tableName( $destTable );
996 
997  if ( !is_array( $insertOptions ) ) {
998  $insertOptions = array( $insertOptions );
999  }
1000 
1001  /*
1002  * If IGNORE is set, we use savepoints to emulate mysql's behavior
1003  * Ignore LOW PRIORITY option, since it is MySQL-specific
1004  */
1005  $savepoint = null;
1006  if ( in_array( 'IGNORE', $insertOptions ) ) {
1007  $savepoint = new SavepointPostgres( $this, 'mw' );
1008  $olde = error_reporting( 0 );
1009  $numrowsinserted = 0;
1010  $savepoint->savepoint();
1011  }
1012 
1013  if ( !is_array( $selectOptions ) ) {
1014  $selectOptions = array( $selectOptions );
1015  }
1016  list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
1017  if ( is_array( $srcTable ) ) {
1018  $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
1019  } else {
1020  $srcTable = $this->tableName( $srcTable );
1021  }
1022 
1023  $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
1024  " SELECT $startOpts " . implode( ',', $varMap ) .
1025  " FROM $srcTable $useIndex";
1026 
1027  if ( $conds != '*' ) {
1028  $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
1029  }
1030 
1031  $sql .= " $tailOpts";
1032 
1033  $res = (bool)$this->query( $sql, $fname, $savepoint );
1034  if ( $savepoint ) {
1035  $bar = pg_last_error();
1036  if ( $bar != false ) {
1037  $savepoint->rollback();
1038  } else {
1039  $savepoint->release();
1040  $numrowsinserted++;
1041  }
1042  error_reporting( $olde );
1043  $savepoint->commit();
1044 
1045  // Set the affected row count for the whole operation
1046  $this->mAffectedRows = $numrowsinserted;
1047 
1048  // IGNORE always returns true
1049  return true;
1050  }
1051 
1052  return $res;
1053  }
1054 
1055  function tableName( $name, $format = 'quoted' ) {
1056  # Replace reserved words with better ones
1057  switch ( $name ) {
1058  case 'user':
1059  return $this->realTableName( 'mwuser', $format );
1060  case 'text':
1061  return $this->realTableName( 'pagecontent', $format );
1062  default:
1063  return $this->realTableName( $name, $format );
1064  }
1065  }
1066 
1067  /* Don't cheat on installer */
1068  function realTableName( $name, $format = 'quoted' ) {
1069  return parent::tableName( $name, $format );
1070  }
1078  function nextSequenceValue( $seqName ) {
1079  $safeseq = str_replace( "'", "''", $seqName );
1080  $res = $this->query( "SELECT nextval('$safeseq')" );
1081  $row = $this->fetchRow( $res );
1082  $this->mInsertId = $row[0];
1083 
1084  return $this->mInsertId;
1085  }
1086 
1093  function currentSequenceValue( $seqName ) {
1094  $safeseq = str_replace( "'", "''", $seqName );
1095  $res = $this->query( "SELECT currval('$safeseq')" );
1096  $row = $this->fetchRow( $res );
1097  $currval = $row[0];
1098 
1099  return $currval;
1100  }
1101 
1102  # Returns the size of a text field, or -1 for "unlimited"
1103  function textFieldSize( $table, $field ) {
1104  $table = $this->tableName( $table );
1105  $sql = "SELECT t.typname as ftype,a.atttypmod as size
1106  FROM pg_class c, pg_attribute a, pg_type t
1107  WHERE relname='$table' AND a.attrelid=c.oid AND
1108  a.atttypid=t.oid and a.attname='$field'";
1109  $res = $this->query( $sql );
1110  $row = $this->fetchObject( $res );
1111  if ( $row->ftype == 'varchar' ) {
1112  $size = $row->size - 4;
1113  } else {
1114  $size = $row->size;
1115  }
1116 
1117  return $size;
1118  }
1119 
1120  function limitResult( $sql, $limit, $offset = false ) {
1121  return "$sql LIMIT $limit " . ( is_numeric( $offset ) ? " OFFSET {$offset} " : '' );
1122  }
1123 
1124  function wasDeadlock() {
1125  return $this->lastErrno() == '40P01';
1126  }
1127 
1128  function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) {
1129  $newName = $this->addIdentifierQuotes( $newName );
1130  $oldName = $this->addIdentifierQuotes( $oldName );
1131 
1132  return $this->query( 'CREATE ' . ( $temporary ? 'TEMPORARY ' : '' ) . " TABLE $newName " .
1133  "(LIKE $oldName INCLUDING DEFAULTS)", $fname );
1134  }
1135 
1136  function listTables( $prefix = null, $fname = __METHOD__ ) {
1137  $eschema = $this->addQuotes( $this->getCoreSchema() );
1138  $result = $this->query( "SELECT tablename FROM pg_tables WHERE schemaname = $eschema", $fname );
1139  $endArray = array();
1140 
1141  foreach ( $result as $table ) {
1142  $vars = get_object_vars( $table );
1143  $table = array_pop( $vars );
1144  if ( !$prefix || strpos( $table, $prefix ) === 0 ) {
1145  $endArray[] = $table;
1146  }
1147  }
1148 
1149  return $endArray;
1150  }
1151 
1152  function timestamp( $ts = 0 ) {
1153  return wfTimestamp( TS_POSTGRES, $ts );
1154  }
1155 
1156  /*
1157  * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12
1158  * to http://www.php.net/manual/en/ref.pgsql.php
1159  *
1160  * Parsing a postgres array can be a tricky problem, he's my
1161  * take on this, it handles multi-dimensional arrays plus
1162  * escaping using a nasty regexp to determine the limits of each
1163  * data-item.
1164  *
1165  * This should really be handled by PHP PostgreSQL module
1166  *
1167  * @since 1.19
1168  * @param string $text Postgreql array returned in a text form like {a,b}
1169  * @param string $output
1170  * @param int $limit
1171  * @param int $offset
1172  * @return string
1173  */
1174  function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) {
1175  if ( false === $limit ) {
1176  $limit = strlen( $text ) - 1;
1177  $output = array();
1178  }
1179  if ( '{}' == $text ) {
1180  return $output;
1181  }
1182  do {
1183  if ( '{' != $text[$offset] ) {
1184  preg_match( "/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/",
1185  $text, $match, 0, $offset );
1186  $offset += strlen( $match[0] );
1187  $output[] = ( '"' != $match[1][0]
1188  ? $match[1]
1189  : stripcslashes( substr( $match[1], 1, -1 ) ) );
1190  if ( '},' == $match[3] ) {
1191  return $output;
1192  }
1193  } else {
1194  $offset = $this->pg_array_parse( $text, $output, $limit, $offset + 1 );
1195  }
1196  } while ( $limit > $offset );
1197 
1198  return $output;
1199  }
1200 
1204  public function aggregateValue( $valuedata, $valuename = 'value' ) {
1205  return $valuedata;
1206  }
1211  public function getSoftwareLink() {
1212  return '[{{int:version-db-postgres-url}} PostgreSQL]';
1213  }
1214 
1222  function getCurrentSchema() {
1223  $res = $this->query( "SELECT current_schema()", __METHOD__ );
1224  $row = $this->fetchRow( $res );
1225 
1226  return $row[0];
1227  }
1228 
1239  function getSchemas() {
1240  $res = $this->query( "SELECT current_schemas(false)", __METHOD__ );
1241  $row = $this->fetchRow( $res );
1242  $schemas = array();
1243 
1244  /* PHP pgsql support does not support array type, "{a,b}" string is returned */
1245 
1246  return $this->pg_array_parse( $row[0], $schemas );
1247  }
1248 
1258  function getSearchPath() {
1259  $res = $this->query( "SHOW search_path", __METHOD__ );
1260  $row = $this->fetchRow( $res );
1261 
1262  /* PostgreSQL returns SHOW values as strings */
1263 
1264  return explode( ",", $row[0] );
1265  }
1266 
1274  function setSearchPath( $search_path ) {
1275  $this->query( "SET search_path = " . implode( ", ", $search_path ) );
1276  }
1277 
1292  function determineCoreSchema( $desiredSchema ) {
1293  $this->begin( __METHOD__ );
1294  if ( $this->schemaExists( $desiredSchema ) ) {
1295  if ( in_array( $desiredSchema, $this->getSchemas() ) ) {
1296  $this->mCoreSchema = $desiredSchema;
1297  wfDebug( "Schema \"" . $desiredSchema . "\" already in the search path\n" );
1298  } else {
1304  $search_path = $this->getSearchPath();
1305  array_unshift( $search_path,
1306  $this->addIdentifierQuotes( $desiredSchema ) );
1307  $this->setSearchPath( $search_path );
1308  $this->mCoreSchema = $desiredSchema;
1309  wfDebug( "Schema \"" . $desiredSchema . "\" added to the search path\n" );
1310  }
1311  } else {
1312  $this->mCoreSchema = $this->getCurrentSchema();
1313  wfDebug( "Schema \"" . $desiredSchema . "\" not found, using current \"" .
1314  $this->mCoreSchema . "\"\n" );
1315  }
1316  /* Commit SET otherwise it will be rollbacked on error or IGNORE SELECT */
1317  $this->commit( __METHOD__ );
1318  }
1319 
1326  function getCoreSchema() {
1328  }
1329 
1333  function getServerVersion() {
1334  if ( !isset( $this->numericVersion ) ) {
1335  $versionInfo = pg_version( $this->mConn );
1336  if ( version_compare( $versionInfo['client'], '7.4.0', 'lt' ) ) {
1337  // Old client, abort install
1338  $this->numericVersion = '7.3 or earlier';
1339  } elseif ( isset( $versionInfo['server'] ) ) {
1340  // Normal client
1341  $this->numericVersion = $versionInfo['server'];
1342  } else {
1343  // Bug 16937: broken pgsql extension from PHP<5.3
1344  $this->numericVersion = pg_parameter_status( $this->mConn, 'server_version' );
1345  }
1346  }
1347 
1348  return $this->numericVersion;
1349  }
1350 
1359  function relationExists( $table, $types, $schema = false ) {
1360  if ( !is_array( $types ) ) {
1361  $types = array( $types );
1362  }
1363  if ( !$schema ) {
1364  $schema = $this->getCoreSchema();
1365  }
1366  $table = $this->realTableName( $table, 'raw' );
1367  $etable = $this->addQuotes( $table );
1368  $eschema = $this->addQuotes( $schema );
1369  $sql = "SELECT 1 FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "
1370  . "WHERE c.relnamespace = n.oid AND c.relname = $etable AND n.nspname = $eschema "
1371  . "AND c.relkind IN ('" . implode( "','", $types ) . "')";
1372  $res = $this->query( $sql );
1373  $count = $res ? $res->numRows() : 0;
1374 
1375  return (bool)$count;
1376  }
1377 
1386  function tableExists( $table, $fname = __METHOD__, $schema = false ) {
1387  return $this->relationExists( $table, array( 'r', 'v' ), $schema );
1388  }
1389 
1390  function sequenceExists( $sequence, $schema = false ) {
1391  return $this->relationExists( $sequence, 'S', $schema );
1392  }
1393 
1394  function triggerExists( $table, $trigger ) {
1395  $q = <<<SQL
1396  SELECT 1 FROM pg_class, pg_namespace, pg_trigger
1397  WHERE relnamespace=pg_namespace.oid AND relkind='r'
1398  AND tgrelid=pg_class.oid
1399  AND nspname=%s AND relname=%s AND tgname=%s
1400 SQL;
1401  $res = $this->query(
1402  sprintf(
1403  $q,
1404  $this->addQuotes( $this->getCoreSchema() ),
1405  $this->addQuotes( $table ),
1406  $this->addQuotes( $trigger )
1407  )
1408  );
1409  if ( !$res ) {
1410  return null;
1411  }
1412  $rows = $res->numRows();
1413 
1414  return $rows;
1415  }
1416 
1417  function ruleExists( $table, $rule ) {
1418  $exists = $this->selectField( 'pg_rules', 'rulename',
1419  array(
1420  'rulename' => $rule,
1421  'tablename' => $table,
1422  'schemaname' => $this->getCoreSchema()
1423  )
1424  );
1425 
1426  return $exists === $rule;
1427  }
1428 
1429  function constraintExists( $table, $constraint ) {
1430  $sql = sprintf( "SELECT 1 FROM information_schema.table_constraints " .
1431  "WHERE constraint_schema = %s AND table_name = %s AND constraint_name = %s",
1432  $this->addQuotes( $this->getCoreSchema() ),
1433  $this->addQuotes( $table ),
1434  $this->addQuotes( $constraint )
1435  );
1436  $res = $this->query( $sql );
1437  if ( !$res ) {
1438  return null;
1439  }
1440  $rows = $res->numRows();
1441 
1442  return $rows;
1443  }
1444 
1450  function schemaExists( $schema ) {
1451  $exists = $this->selectField( '"pg_catalog"."pg_namespace"', 1,
1452  array( 'nspname' => $schema ), __METHOD__ );
1453 
1454  return (bool)$exists;
1455  }
1456 
1462  function roleExists( $roleName ) {
1463  $exists = $this->selectField( '"pg_catalog"."pg_roles"', 1,
1464  array( 'rolname' => $roleName ), __METHOD__ );
1465 
1466  return (bool)$exists;
1467  }
1468 
1469  function fieldInfo( $table, $field ) {
1470  return PostgresField::fromText( $this, $table, $field );
1471  }
1472 
1479  function fieldType( $res, $index ) {
1480  if ( $res instanceof ResultWrapper ) {
1481  $res = $res->result;
1482  }
1483 
1484  return pg_field_type( $res, $index );
1485  }
1486 
1491  function encodeBlob( $b ) {
1492  return new Blob( pg_escape_bytea( $this->mConn, $b ) );
1493  }
1494 
1495  function decodeBlob( $b ) {
1496  if ( $b instanceof Blob ) {
1497  $b = $b->fetch();
1498  }
1499 
1500  return pg_unescape_bytea( $b );
1501  }
1502 
1503  function strencode( $s ) { # Should not be called by us
1504  return pg_escape_string( $this->mConn, $s );
1505  }
1506 
1511  function addQuotes( $s ) {
1512  if ( is_null( $s ) ) {
1513  return 'NULL';
1514  } elseif ( is_bool( $s ) ) {
1515  return intval( $s );
1516  } elseif ( $s instanceof Blob ) {
1517  return "'" . $s->fetch( $s ) . "'";
1518  }
1519 
1520  return "'" . pg_escape_string( $this->mConn, $s ) . "'";
1521  }
1522 
1530  protected function replaceVars( $ins ) {
1531  $ins = parent::replaceVars( $ins );
1532 
1533  if ( $this->numericVersion >= 8.3 ) {
1534  // Thanks for not providing backwards-compatibility, 8.3
1535  $ins = preg_replace( "/to_tsvector\s*\(\s*'default'\s*,/", 'to_tsvector(', $ins );
1536  }
1537 
1538  if ( $this->numericVersion <= 8.1 ) { // Our minimum version
1539  $ins = str_replace( 'USING gin', 'USING gist', $ins );
1540  }
1541 
1542  return $ins;
1543  }
1544 
1552  function makeSelectOptions( $options ) {
1553  $preLimitTail = $postLimitTail = '';
1554  $startOpts = $useIndex = '';
1555 
1556  $noKeyOptions = array();
1557  foreach ( $options as $key => $option ) {
1558  if ( is_numeric( $key ) ) {
1559  $noKeyOptions[$option] = true;
1560  }
1561  }
1563  $preLimitTail .= $this->makeGroupByWithHaving( $options );
1564 
1565  $preLimitTail .= $this->makeOrderBy( $options );
1567  //if ( isset( $options['LIMIT'] ) ) {
1568  // $tailOpts .= $this->limitResult( '', $options['LIMIT'],
1569  // isset( $options['OFFSET'] ) ? $options['OFFSET']
1570  // : false );
1571  //}
1572 
1573  if ( isset( $options['FOR UPDATE'] ) ) {
1574  $postLimitTail .= ' FOR UPDATE OF ' . implode( ', ', $options['FOR UPDATE'] );
1575  } elseif ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
1576  $postLimitTail .= ' FOR UPDATE';
1577  }
1579  if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) {
1580  $startOpts .= 'DISTINCT';
1581  }
1582 
1583  return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
1584  }
1585 
1586  function getDBname() {
1587  return $this->mDBname;
1588  }
1589 
1590  function getServer() {
1591  return $this->mServer;
1592  }
1593 
1594  function buildConcat( $stringList ) {
1595  return implode( ' || ', $stringList );
1596  }
1597 
1598  public function buildGroupConcatField(
1599  $delimiter, $table, $field, $conds = '', $options = array(), $join_conds = array()
1600  ) {
1601  $fld = "array_to_string(array_agg($field)," . $this->addQuotes( $delimiter ) . ')';
1602 
1603  return '(' . $this->selectSQLText( $table, $fld, $conds, null, array(), $join_conds ) . ')';
1604  }
1605 
1606  public function getSearchEngine() {
1607  return 'SearchPostgres';
1608  }
1609 
1610  public function streamStatementEnd( &$sql, &$newLine ) {
1611  # Allow dollar quoting for function declarations
1612  if ( substr( $newLine, 0, 4 ) == '$mw$' ) {
1613  if ( $this->delimiter ) {
1614  $this->delimiter = false;
1615  } else {
1616  $this->delimiter = ';';
1617  }
1618  }
1619 
1620  return parent::streamStatementEnd( $sql, $newLine );
1621  }
1622 
1632  public function lockIsFree( $lockName, $method ) {
1633  $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
1634  $result = $this->query( "SELECT (CASE(pg_try_advisory_lock($key))
1635  WHEN 'f' THEN 'f' ELSE pg_advisory_unlock($key) END) AS lockstatus", $method );
1636  $row = $this->fetchObject( $result );
1637 
1638  return ( $row->lockstatus === 't' );
1639  }
1648  public function lock( $lockName, $method, $timeout = 5 ) {
1649  $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
1650  for ( $attempts = 1; $attempts <= $timeout; ++$attempts ) {
1651  $result = $this->query(
1652  "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
1653  $row = $this->fetchObject( $result );
1654  if ( $row->lockstatus === 't' ) {
1655  return true;
1656  } else {
1657  sleep( 1 );
1658  }
1659  }
1660  wfDebug( __METHOD__ . " failed to acquire lock\n" );
1661 
1662  return false;
1663  }
1664 
1672  public function unlock( $lockName, $method ) {
1673  $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
1674  $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
1675  $row = $this->fetchObject( $result );
1676 
1677  return ( $row->lockstatus === 't' );
1678  }
1679 
1684  private function bigintFromLockName( $lockName ) {
1685  return wfBaseConvert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
1686  }
1687 } // end DatabasePostgres class
DatabasePostgres\indexUnique
indexUnique( $table, $index, $fname=__METHOD__)
Definition: DatabasePostgres.php:777
DatabasePostgres\relationExists
relationExists( $table, $types, $schema=false)
Query whether a given relation exists (in the given schema, or the default mw one if not given)
Definition: DatabasePostgres.php:1327
DatabasePostgres\fieldInfo
fieldInfo( $table, $field)
mysql_fetch_field() wrapper Returns false if the field doesn't exist
Definition: DatabasePostgres.php:1437
DatabasePostgres\strictIPs
strictIPs()
Returns true if this database is strict about what can be put into an IP field.
Definition: DatabasePostgres.php:295
$result
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message. Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item. $reader:XMLReader object $logInfo:Array of information Return false to stop further processing of the tag 'ImportHandlePageXMLTag':When parsing a XML tag in a page. $reader:XMLReader object $pageInfo:Array of information Return false to stop further processing of the tag 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision. $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information Return false to stop further processing of the tag 'ImportHandleToplevelXMLTag':When parsing a top level XML tag. $reader:XMLReader object Return false to stop further processing of the tag 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload. $reader:XMLReader object $revisionInfo:Array of information Return false to stop further processing of the tag 'InfoAction':When building information to display on the action=info page. $context:IContextSource object & $pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect. $title:Title object for the current page $request:WebRequest $ignoreRedirect:boolean to skip redirect check $target:Title/string of redirect target $article:Article object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not. Return true without providing an interwiki to continue interwiki search. $prefix:interwiki prefix we are looking for. & $iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InternalParseBeforeSanitize':during Parser 's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings. Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InternalParseBeforeLinks':during Parser 's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings. & $parser:Parser object & $text:string containing partially parsed text & $stripState:Parser 's internal StripState object 'InvalidateEmailComplete':Called after a user 's email has been invalidated successfully. $user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification. Callee may modify $url and $query, URL will be constructed as $url . $query & $url:URL to index.php & $query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) $article:article(object) being checked 'IsTrustedProxy':Override the result of wfIsTrustedProxy() $ip:IP being check $result:Change this value to override the result of wfIsTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from & $allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of User::isValidEmailAddr(), for instance to return false if the domain name doesn 't match your organization. $addr:The e-mail address entered by the user & $result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user & $result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we 're looking for a messages file for & $file:The messages file path, you can override this to change the location. 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces. Do not use this hook to add namespaces. Use CanonicalNamespaces for that. & $namespaces:Array of namespaces indexed by their numbers 'LanguageGetMagic':DEPRECATED, use $magicWords in a file listed in $wgExtensionMessagesFiles instead. Use this to define synonyms of magic words depending of the language $magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetSpecialPageAliases':DEPRECATED, use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead. Use to define aliases of special pages names depending of the language $specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names. & $names:array of language code=> language name $code language of the preferred translations 'LanguageLinks':Manipulate a page 's language links. This is called in various places to allow extensions to define the effective language links for a page. $title:The page 's Title. & $links:Associative array mapping language codes to prefixed links of the form "language:title". & $linkFlags:Associative array mapping prefixed links to arrays of flags. Currently unused, but planned to provide support for marking individual language links in the UI, e.g. for featured articles. 'LinkBegin':Used when generating internal and interwiki links in Linker::link(), before processing starts. Return false to skip default processing and return $ret. See documentation for Linker::link() for details on the expected meanings of parameters. $skin:the Skin object $target:the Title that the link is pointing to & $html:the contents that the< a > tag should have(raw HTML) $result
Definition: hooks.txt:1528
DatabasePostgres\insert
insert( $table, $args, $fname=__METHOD__, $options=array())
INSERT wrapper, inserts an array into a table.
Definition: DatabasePostgres.php:835
DatabasePostgres\insertSelect
insertSelect( $destTable, $srcTable, $varMap, $conds, $fname=__METHOD__, $insertOptions=array(), $selectOptions=array())
INSERT SELECT wrapper $varMap must be an associative array of the form array( 'dest1' => 'source1',...
Definition: DatabasePostgres.php:961
DatabasePostgres\getSchemas
getSchemas()
Return list of schemas which are accessible without schema name This is list does not contain magic k...
Definition: DatabasePostgres.php:1207
PostgresField\$tablename
$tablename
Definition: DatabasePostgres.php:25
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
SavepointPostgres\query
query( $keyword, $msg_ok, $msg_failed)
Definition: DatabasePostgres.php:228
DatabasePostgres\affectedRows
affectedRows()
Get the number of rows affected by the last write query.
Definition: DatabasePostgres.php:645
DatabaseBase\$delimiter
$delimiter
Definition: Database.php:258
PostgresField\fromText
static fromText( $db, $table, $field)
Definition: DatabasePostgres.php:34
DatabasePostgres\wasDeadlock
wasDeadlock()
Determines if the last failure was due to a deadlock STUB.
Definition: DatabasePostgres.php:1092
PostgresField\conname
conname()
Definition: DatabasePostgres.php:114
PostgresField\$max_length
$max_length
Definition: DatabasePostgres.php:25
DatabasePostgres\getCurrentSchema
getCurrentSchema()
Return current schema (executes SELECT current_schema()) Needs transaction.
Definition: DatabasePostgres.php:1190
Field
Base for all database-specific classes representing information about database fields.
Definition: DatabaseUtility.php:69
is
We use the convention $dbr for read and $dbw for write to help you keep track of whether the database object is a the world will explode Or to be a subsequent write query which succeeded on the master may fail when replicated to the slave due to a unique key collision Replication on the slave will stop and it may take hours to repair the database and get it back online Setting read_only in my cnf on the slave will avoid this but given the dire we prefer to have as many checks as possible We provide a but the wrapper functions like please read the documentation for except in special pages derived from QueryPage It s a common pitfall for new developers to submit code containing SQL queries which examine huge numbers of rows Remember that COUNT * is(N), counting rows in atable is like counting beans in a bucket.------------------------------------------------------------------------ Replication------------------------------------------------------------------------The largest installation of MediaWiki, Wikimedia, uses a large set ofslave MySQL servers replicating writes made to a master MySQL server. Itis important to understand the issues associated with this setup if youwant to write code destined for Wikipedia.It 's often the case that the best algorithm to use for a given taskdepends on whether or not replication is in use. Due to our unabashedWikipedia-centrism, we often just use the replication-friendly version, but if you like, you can use wfGetLB() ->getServerCount() > 1 tocheck to see if replication is in use.===Lag===Lag primarily occurs when large write queries are sent to the master.Writes on the master are executed in parallel, but they are executed inserial when they are replicated to the slaves. The master writes thequery to the binlog when the transaction is committed. The slaves pollthe binlog and start executing the query as soon as it appears. They canservice reads while they are performing a write query, but will not readanything more from the binlog and thus will perform no more writes. Thismeans that if the write query runs for a long time, the slaves will lagbehind the master for the time it takes for the write query to complete.Lag can be exacerbated by high read load. MediaWiki 's load balancer willstop sending reads to a slave when it is lagged by more than 30 seconds.If the load ratios are set incorrectly, or if there is too much loadgenerally, this may lead to a slave permanently hovering around 30seconds lag.If all slaves are lagged by more than 30 seconds, MediaWiki will stopwriting to the database. All edits and other write operations will berefused, with an error returned to the user. This gives the slaves achance to catch up. Before we had this mechanism, the slaves wouldregularly lag by several minutes, making review of recent editsdifficult.In addition to this, MediaWiki attempts to ensure that the user seesevents occurring on the wiki in chronological order. A few seconds of lagcan be tolerated, as long as the user sees a consistent picture fromsubsequent requests. This is done by saving the master binlog positionin the session, and then at the start of each request, waiting for theslave to catch up to that position before doing any reads from it. Ifthis wait times out, reads are allowed anyway, but the request isconsidered to be in "lagged slave mode". Lagged slave mode can bechecked by calling wfGetLB() ->getLaggedSlaveMode(). The onlypractical consequence at present is a warning displayed in the pagefooter.===Lag avoidance===To avoid excessive lag, queries which write large numbers of rows shouldbe split up, generally to write one row at a time. Multi-row INSERT ...SELECT queries are the worst offenders should be avoided altogether.Instead do the select first and then the insert.===Working with lag===Despite our best efforts, it 's not practical to guarantee a low-lagenvironment. Lag will usually be less than one second, but mayoccasionally be up to 30 seconds. For scalability, it 's very importantto keep load on the master low, so simply sending all your queries tothe master is not the answer. So when you have a genuine need forup-to-date data, the following approach is advised:1) Do a quick query to the master for a sequence number or timestamp 2) Run the full query on the slave and check if it matches the data you gotfrom the master 3) If it doesn 't, run the full query on the masterTo avoid swamping the master every time the slaves lag, use of thisapproach should be kept to a minimum. In most cases you should just readfrom the slave and let the user deal with the delay.------------------------------------------------------------------------ Lock contention------------------------------------------------------------------------Due to the high write rate on Wikipedia(and some other wikis), MediaWiki developers need to be very careful to structure their writesto avoid long-lasting locks. By default, MediaWiki opens a transactionat the first query, and commits it before the output is sent. Locks willbe held from the time when the query is done until the commit. So youcan reduce lock time by doing as much processing as possible before youdo your write queries.Often this approach is not good enough, and it becomes necessary toenclose small groups of queries in their own transaction. Use thefollowing syntax:$dbw=wfGetDB(DB_MASTER
DatabasePostgres\replaceVars
replaceVars( $ins)
Postgres specific version of replaceVars.
Definition: DatabasePostgres.php:1498
DatabasePostgres\reportQueryError
reportQueryError( $error, $errno, $sql, $fname, $tempIgnore=false)
Report a query error.
Definition: DatabasePostgres.php:491
DatabasePostgres\listTables
listTables( $prefix=null, $fname=__METHOD__)
List all tables on the database.
Definition: DatabasePostgres.php:1104
DatabasePostgres\currentSequenceValue
currentSequenceValue( $seqName)
Return the current value of a sequence.
Definition: DatabasePostgres.php:1061
DatabaseBase\makeList
makeList( $a, $mode=LIST_COMMA)
Makes an encoded list of strings from an array.
Definition: Database.php:1992
PostgresField\tableName
tableName()
Name of table this field belongs to.
Definition: DatabasePostgres.php:90
DatabaseBase\close
close()
Closes a database connection.
Definition: Database.php:914
DatabaseBase\query
query( $sql, $fname=__METHOD__, $tempIgnore=false)
Run an SQL query and return the result.
Definition: Database.php:1001
DatabasePostgres\aggregateValue
aggregateValue( $valuedata, $valuename='value')
Return aggregated value function call.
Definition: DatabasePostgres.php:1172
DatabasePostgres\$mTransactionState
PostgresTransactionState $mTransactionState
Definition: DatabasePostgres.php:279
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:2483
DatabasePostgres\buildConcat
buildConcat( $stringList)
Build a concatenation list to feed into a SQL query.
Definition: DatabasePostgres.php:1562
SavepointPostgres\$didbegin
$didbegin
Definition: DatabasePostgres.php:197
DatabasePostgres\implicitGroupby
implicitGroupby()
Returns true if this database does an implicit sort when doing GROUP BY.
Definition: DatabasePostgres.php:303
DatabasePostgres\$numericVersion
float string $numericVersion
Definition: DatabasePostgres.php:275
$n
$n
Definition: RandomTest.php:76
wfSuppressWarnings
wfSuppressWarnings( $end=false)
Reference-counted warning suppression.
Definition: GlobalFunctions.php:2387
PostgresTransactionState\check
check()
Definition: DatabasePostgres.php:153
DatabasePostgres\lock
lock( $lockName, $method, $timeout=5)
See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS.
Definition: DatabasePostgres.php:1616
$fname
if(!defined( 'MEDIAWIKI')) $fname
This file is not a valid entry point, perform no further processing unless MEDIAWIKI is defined.
Definition: Setup.php:35
DatabasePostgres\setSearchPath
setSearchPath( $search_path)
Update search_path, values should already be sanitized Values may contain magic keywords like "$user"...
Definition: DatabasePostgres.php:1242
$limit
if( $sleep) $limit
Definition: importImages.php:99
DatabaseBase\makeOrderBy
makeOrderBy( $options)
Returns an optional ORDER BY.
Definition: Database.php:1424
DatabasePostgres\doQuery
doQuery( $sql)
The DBMS-dependent part of query()
Definition: DatabasePostgres.php:452
DatabasePostgres\cascadingDeletes
cascadingDeletes()
Returns true if this database supports (and uses) cascading deletes.
Definition: DatabasePostgres.php:287
DatabasePostgres\selectSQLText
selectSQLText( $table, $vars, $conds='', $fname=__METHOD__, $options=array(), $join_conds=array())
Change the FOR UPDATE option as necessary based on the join conditions.
Definition: DatabasePostgres.php:800
n
if(! $in) print Initializing normalization quick check tables n
Definition: UtfNormalGenerate.php:36
e
in this case you re responsible for computing and outputting the entire conflict i e
Definition: hooks.txt:1038
Blob
Utility class.
Definition: DatabaseUtility.php:53
$s
$s
Definition: mergeMessageFileList.php:156
DatabasePostgres\fieldName
fieldName( $res, $n)
Get a field name in a result object.
Definition: DatabasePostgres.php:594
DatabasePostgres\getSearchEngine
getSearchEngine()
Get search engine class.
Definition: DatabasePostgres.php:1574
PostgresTransactionState\$WATCHED
static $WATCHED
Definition: DatabasePostgres.php:116
DatabasePostgres\unlock
unlock( $lockName, $method)
See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKSFROM PG DO...
Definition: DatabasePostgres.php:1640
DatabasePostgres\indexAttributes
indexAttributes( $index, $schema=false)
Returns is of attributes used in index.
Definition: DatabasePostgres.php:720
DatabasePostgres
Definition: DatabasePostgres.php:268
DatabasePostgres\makeConnectionString
makeConnectionString( $vars)
Definition: DatabasePostgres.php:434
PostgresField\defaultValue
defaultValue()
Definition: DatabasePostgres.php:121
DatabasePostgres\freeResult
freeResult( $res)
Definition: DatabasePostgres.php:514
PostgresField\isNullable
isNullable()
Whether this field can store NULL values.
Definition: DatabasePostgres.php:98
LIST_AND
const LIST_AND
Definition: Defines.php:203
DatabasePostgres\getServerVersion
getServerVersion()
Definition: DatabasePostgres.php:1301
PostgresField\name
name()
Field name.
Definition: DatabasePostgres.php:86
PostgresField\$default
$default
Definition: DatabasePostgres.php:25
DatabasePostgres\$mLastResult
resource $mLastResult
Definition: DatabasePostgres.php:269
DatabasePostgres\makeSelectOptions
makeSelectOptions( $options)
Various select options.
Definition: DatabasePostgres.php:1520
DatabasePostgres\searchableIPs
searchableIPs()
Returns true if this database can do a native search on IP columns e.g.
Definition: DatabasePostgres.php:311
DatabasePostgres\buildGroupConcatField
buildGroupConcatField( $delimiter, $table, $field, $conds='', $options=array(), $join_conds=array())
Definition: DatabasePostgres.php:1566
DatabasePostgres\numFields
numFields( $res)
Get the number of fields in a result object.
Definition: DatabasePostgres.php:586
DatabaseBase\indexName
indexName( $index)
Get the name of an index in a given table.
Definition: Database.php:2456
DatabasePostgres\getServer
getServer()
Get the server hostname or IP address.
Definition: DatabasePostgres.php:1558
DatabaseBase\selectField
selectField( $table, $var, $cond='', $fname=__METHOD__, $options=array())
A SELECT wrapper which returns a single field from a single result row.
Definition: Database.php:1281
PostgresTransactionState\log_changed
log_changed( $old, $new, $watched)
Definition: DatabasePostgres.php:180
DatabasePostgres\selectDB
selectDB( $db)
Postgres doesn't support selectDB in the same way MySQL does.
Definition: DatabasePostgres.php:426
DatabaseBase\$mDBname
$mDBname
Definition: Database.php:237
DatabaseBase\$mConn
resource $mConn
Database connection *.
Definition: Database.php:239
DatabasePostgres\estimateRowCount
estimateRowCount( $table, $vars=' *', $conds='', $fname=__METHOD__, $options=array())
Estimate rows in dataset Returns estimated count, based on EXPLAIN output This is not necessarily an ...
Definition: DatabasePostgres.php:671
SavepointPostgres\savepoint
savepoint()
Definition: DatabasePostgres.php:239
DatabasePostgres\textFieldSize
textFieldSize( $table, $field)
Returns the size of a text field, or -1 for "unlimited".
Definition: DatabasePostgres.php:1071
PostgresTransactionState\$mNewState
array $mNewState
Definition: DatabasePostgres.php:136
PostgresField\$name
$name
Definition: DatabasePostgres.php:25
DatabaseBase\select
select( $table, $vars, $conds='', $fname=__METHOD__, $options=array(), $join_conds=array())
Execute a SELECT query constructed using the various parameters provided.
Definition: Database.php:1575
wfRestoreWarnings
wfRestoreWarnings()
Restore error level to previous value.
Definition: GlobalFunctions.php:2417
DatabasePostgres\getSoftwareLink
getSoftwareLink()
Definition: DatabasePostgres.php:1179
$wgCommandLineMode
global $wgCommandLineMode
Definition: Setup.php:401
tableName
We use the convention $dbr for read and $dbw for write to help you keep track of whether the database object is a the world will explode Or to be a subsequent write query which succeeded on the master may fail when replicated to the slave due to a unique key collision Replication on the slave will stop and it may take hours to repair the database and get it back online Setting read_only in my cnf on the slave will avoid this but given the dire we prefer to have as many checks as possible We provide a but the wrapper functions like please read the documentation for tableName() and addQuotes(). You will need both of them. ------------------------------------------------------------------------ Basic query optimisation ------------------------------------------------------------------------ MediaWiki developers who need to write DB queries should have some understanding of databases and the performance issues associated with them. Patches containing unacceptably slow features will not be accepted. Unindexed queries are generally not welcome in MediaWiki
DatabasePostgres\open
open( $server, $user, $password, $dbName)
Usually aborts on failure.
Definition: DatabasePostgres.php:338
PostgresField\$has_default
$has_default
Definition: DatabasePostgres.php:25
DatabaseBase\restoreErrorHandler
restoreErrorHandler()
Definition: Database.php:884
PostgresTransactionState\describe_changed
describe_changed( $status, $desc_table)
Definition: DatabasePostgres.php:172
DatabasePostgres\decodeBlob
decodeBlob( $b)
Some DBMSs return a special placeholder object representing blob fields in result objects.
Definition: DatabasePostgres.php:1463
DatabasePostgres\closeConnection
closeConnection()
Closes a database connection, if it is open Returns success, true if already closed.
Definition: DatabasePostgres.php:448
PostgresField\$nullable
$nullable
Definition: DatabasePostgres.php:25
PostgresField\$deferred
$deferred
Definition: DatabasePostgres.php:25
PostgresField\maxLength
maxLength()
Definition: DatabasePostgres.php:102
DatabasePostgres\limitResult
limitResult( $sql, $limit, $offset=false)
Construct a LIMIT query with optional offset.
Definition: DatabasePostgres.php:1088
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
DatabasePostgres\realTimestamps
realTimestamps()
Returns true if this database uses timestamps rather than integers.
Definition: DatabasePostgres.php:299
DatabasePostgres\timestamp
timestamp( $ts=0)
Convert a timestamp in one of the formats accepted by wfTimestamp() to the format used for inserting ...
Definition: DatabasePostgres.php:1120
DatabasePostgres\fetchObject
fetchObject( $res)
Definition: DatabasePostgres.php:531
DatabasePostgres\insertId
insertId()
Return the result of the last call to nextSequenceValue(); This must be called after nextSequenceValu...
Definition: DatabasePostgres.php:608
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
cssjanus.LEFT
string LEFT
Definition: cssjanus.py:48
DBO_SSL
const DBO_SSL
Definition: Defines.php:47
DBConnectionError
Definition: DatabaseError.php:98
DatabasePostgres\$mAffectedRows
int $mAffectedRows
The number of rows affected as an integer *.
Definition: DatabasePostgres.php:271
DBUnexpectedError
Definition: DatabaseError.php:438
SavepointPostgres
Manage savepoints within a transaction.
Definition: DatabasePostgres.php:194
DatabasePostgres\getSearchPath
getSearchPath()
Return search patch for schemas This is different from getSchemas() since it contain magic keywords (...
Definition: DatabasePostgres.php:1226
DatabasePostgres\tableName
tableName( $name, $format='quoted')
Format a table name ready for use in constructing an SQL query.
Definition: DatabasePostgres.php:1023
PostgresTransactionState
Used to debug transaction processing Only used if $wgDebugDBTransactions is true.
Definition: DatabasePostgres.php:115
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:188
DatabasePostgres\fetchRow
fetchRow( $res)
Fetch the next row from the given result object, in associative array form.
Definition: DatabasePostgres.php:552
DatabasePostgres\tableExists
tableExists( $table, $fname=__METHOD__, $schema=false)
For backward compatibility, this function checks both tables and views.
Definition: DatabasePostgres.php:1354
PostgresField\is_deferrable
is_deferrable()
Definition: DatabasePostgres.php:106
DatabaseBase\makeGroupByWithHaving
makeGroupByWithHaving( $options)
Returns an optional GROUP BY with an optional HAVING.
Definition: Database.php:1398
PostgresField\$type
$type
Definition: DatabasePostgres.php:25
$options
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped & $options
Definition: hooks.txt:1530
DatabasePostgres\$mCoreSchema
string $mCoreSchema
Definition: DatabasePostgres.php:281
DatabasePostgres\addQuotes
addQuotes( $s)
Definition: DatabasePostgres.php:1479
$ok
$ok
Definition: UtfNormalTest.php:71
DatabasePostgres\lockIsFree
lockIsFree( $lockName, $method)
Check to see if a named lock is available.
Definition: DatabasePostgres.php:1600
DatabaseBase\$mServer
$mServer
Definition: Database.php:237
DatabaseBase\trxLevel
trxLevel()
Gets the current transaction level.
Definition: Database.php:400
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:933
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
DatabasePostgres\streamStatementEnd
streamStatementEnd(&$sql, &$newLine)
Called by sourceStream() to check if we've reached a statement end.
Definition: DatabasePostgres.php:1578
DatabasePostgres\cleanupTriggers
cleanupTriggers()
Returns true if this database supports (and uses) triggers (e.g.
Definition: DatabasePostgres.php:291
DatabasePostgres\nextSequenceValue
nextSequenceValue( $seqName)
Return the next in a sequence, save the value for retrieval via insertId()
Definition: DatabasePostgres.php:1046
DatabasePostgres\sequenceExists
sequenceExists( $sequence, $schema=false)
Definition: DatabasePostgres.php:1358
$size
$size
Definition: RandomTest.php:75
$value
$value
Definition: styleTest.css.php:45
PostgresField\$conname
$conname
Definition: DatabasePostgres.php:25
DatabasePostgres\indexInfo
indexInfo( $table, $index, $fname=__METHOD__)
Returns information about an index If errors are explicitly ignored, returns NULL on failure.
Definition: DatabasePostgres.php:697
SavepointPostgres\rollback
rollback()
Definition: DatabasePostgres.php:253
DatabasePostgres\realTableName
realTableName( $name, $format='quoted')
Definition: DatabasePostgres.php:1036
DatabasePostgres\pg_array_parse
pg_array_parse( $text, &$output, $limit=false, $offset=1)
Definition: DatabasePostgres.php:1142
DatabasePostgres\triggerExists
triggerExists( $table, $trigger)
Definition: DatabasePostgres.php:1362
PostgresTransactionState\update
update()
Definition: DatabasePostgres.php:146
DatabaseBase
Database abstraction object.
Definition: Database.php:219
DatabasePostgres\roleExists
roleExists( $roleName)
Returns true if a given role (i.e.
Definition: DatabasePostgres.php:1430
DatabasePostgres\dataSeek
dataSeek( $res, $row)
Definition: DatabasePostgres.php:617
DatabasePostgres\lastError
lastError()
Get a description of the last error.
Definition: DatabasePostgres.php:625
DatabasePostgres\schemaExists
schemaExists( $schema)
Query whether a given schema exists.
Definition: DatabasePostgres.php:1418
DatabasePostgres\functionalIndexes
functionalIndexes()
Returns true if this database can use functional indexes.
Definition: DatabasePostgres.php:315
SavepointPostgres\$id
$id
Definition: DatabasePostgres.php:196
DatabasePostgres\$connectString
string $connectString
Connect string to open a PostgreSQL connection *.
Definition: DatabasePostgres.php:277
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:237
DatabasePostgres\fieldType
fieldType( $res, $index)
pg_field_type() wrapper
Definition: DatabasePostgres.php:1447
SavepointPostgres\__construct
__construct( $dbw, $id)
Definition: DatabasePostgres.php:203
DatabaseBase\commit
commit( $fname=__METHOD__, $flush='')
Commits a transaction previously started using begin().
Definition: Database.php:3435
PostgresField\is_deferred
is_deferred()
Definition: DatabasePostgres.php:110
$password
return false to override stock group addition can be modified try getUserPermissionsErrors userCan checks are continued by internal code can override on output return false to not delete it return false to override the default password checks this Boolean value will be checked to determine if the password was valid return false to implement your own hashing method & $password
Definition: hooks.txt:2697
DatabaseBase\installErrorHandler
installErrorHandler()
Definition: Database.php:875
DatabaseBase\rollback
rollback( $fname=__METHOD__, $flush='')
Rollback a transaction previously started using begin().
Definition: Database.php:3492
DatabasePostgres\encodeBlob
encodeBlob( $b)
Definition: DatabasePostgres.php:1459
$count
$count
Definition: UtfNormalTest2.php:96
SavepointPostgres\release
release()
Definition: DatabasePostgres.php:246
PostgresTransactionState\__construct
__construct( $conn)
Definition: DatabasePostgres.php:140
DatabasePostgres\getType
getType()
Get the type of the DBMS, as it appears in $wgDBtype.
Definition: DatabasePostgres.php:283
DatabaseBase\addIdentifierQuotes
addIdentifierQuotes( $s)
Quotes an identifier using backticks or "double quotes" depending on the database type.
Definition: Database.php:2498
$args
if( $line===false) $args
Definition: cdb.php:62
DatabasePostgres\implicitOrderby
implicitOrderby()
Returns true if this database does an implicit order by when the column has an index For example: SEL...
Definition: DatabasePostgres.php:307
DatabasePostgres\numRows
numRows( $res)
Get the number of rows in a result object.
Definition: DatabasePostgres.php:569
DatabasePostgres\hasConstraint
hasConstraint( $name)
Definition: DatabasePostgres.php:319
DatabasePostgres\lastErrno
lastErrno()
Get the last error number.
Definition: DatabasePostgres.php:637
DatabasePostgres\$mInsertId
int $mInsertId
Definition: DatabasePostgres.php:273
DatabaseBase\begin
begin( $fname=__METHOD__)
Begin a transaction.
Definition: Database.php:3365
PostgresField
Definition: DatabasePostgres.php:24
on
We ve cleaned up the code here by removing clumps of infrequently used code and moving them off somewhere else It s much easier for someone working with this code to see what s _really_ going on
Definition: hooks.txt:86
wfBaseConvert
wfBaseConvert( $input, $sourceBase, $destBase, $pad=1, $lowercase=true, $engine='auto')
Convert an arbitrarily-long digit string from one numeric base to another, optionally zero-padding to...
Definition: GlobalFunctions.php:3377
DatabasePostgres\ruleExists
ruleExists( $table, $rule)
Definition: DatabasePostgres.php:1385
$output
& $output
Definition: hooks.txt:375
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
DatabasePostgres\bigintFromLockName
bigintFromLockName( $lockName)
Definition: DatabasePostgres.php:1652
$keys
$keys
Definition: testCompression.php:63
DatabasePostgres\getCoreSchema
getCoreSchema()
Return schema name fore core MediaWiki tables.
Definition: DatabasePostgres.php:1294
DatabasePostgres\getDBname
getDBname()
Get the current DB name.
Definition: DatabasePostgres.php:1554
SavepointPostgres\__toString
__toString()
Definition: DatabasePostgres.php:260
TS_POSTGRES
const TS_POSTGRES
Postgres format time.
Definition: GlobalFunctions.php:2467
DatabasePostgres\dumpError
dumpError()
Definition: DatabasePostgres.php:470
PostgresTransactionState\$mCurrentState
array $mCurrentState
Definition: DatabasePostgres.php:138
DatabasePostgres\duplicateTableStructure
duplicateTableStructure( $oldName, $newName, $temporary=false, $fname=__METHOD__)
Creates a new table with structure copied from existing table Note that unlike most database abstract...
Definition: DatabasePostgres.php:1096
$vars
static configuration should be added through ResourceLoaderGetConfigVars instead & $vars
Definition: hooks.txt:1679
$error
usually copyright or history_copyright This message must be in HTML not wikitext $subpages will be ignored and the rest of subPageSubtitle() will run. 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink' whether MediaWiki currently thinks this is a CSS JS page Hooks may change this value to override the return value of Title::isCssOrJsPage(). 'TitleIsAlwaysKnown' whether MediaWiki currently thinks this page is known isMovable() always returns false. $title whether MediaWiki currently thinks this page is movable Hooks may change this value to override the return value of Title::isMovable(). 'TitleIsWikitextPage' whether MediaWiki currently thinks this is a wikitext page Hooks may change this value to override the return value of Title::isWikitextPage() 'TitleMove' use UploadVerification and UploadVerifyFile instead where the first element is the message key and the remaining elements are used as parameters to the message based on mime etc Preferred in most cases over UploadVerification object with all info about the upload string as detected by MediaWiki Handlers will typically only apply for specific mime types object & $error
Definition: hooks.txt:2573
PostgresField\$deferrable
$deferrable
Definition: DatabasePostgres.php:25
DatabasePostgres\strencode
strencode( $s)
Wrapper for addslashes()
Definition: DatabasePostgres.php:1471
$res
$res
Definition: database.txt:21
SavepointPostgres\commit
commit()
Definition: DatabasePostgres.php:221
DatabasePostgres\constraintExists
constraintExists( $table, $constraint)
Definition: DatabasePostgres.php:1397
DatabasePostgres\determineCoreSchema
determineCoreSchema( $desiredSchema)
Determine default schema for MediaWiki core Adjust this session schema search path if desired schema ...
Definition: DatabasePostgres.php:1260
if
if(!function_exists('version_compare')||version_compare(phpversion(), '5.3.2')< 0)
Definition: api.php:37
SavepointPostgres\__destruct
__destruct()
Definition: DatabasePostgres.php:214
ResultWrapper
Result wrapper for grabbing data queried by someone else.
Definition: DatabaseUtility.php:99
DatabasePostgres\queryIgnore
queryIgnore( $sql, $fname=__METHOD__)
Definition: DatabasePostgres.php:506
PostgresField\type
type()
Database type.
Definition: DatabasePostgres.php:94
SavepointPostgres\$dbw
DatabaseBase $dbw
Establish a savepoint within a transaction *.
Definition: DatabasePostgres.php:195