MediaWiki  1.23.1
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 
830  function selectSQLText( $table, $vars, $conds = '', $fname = __METHOD__,
831  $options = array(), $join_conds = array()
832  ) {
833  if ( is_array( $options ) ) {
834  $forUpdateKey = array_search( 'FOR UPDATE', $options );
835  if ( $forUpdateKey !== false && $join_conds ) {
836  unset( $options[$forUpdateKey] );
837 
838  foreach ( $join_conds as $table_cond => $join_cond ) {
839  if ( 0 === preg_match( '/^(?:LEFT|RIGHT|FULL)(?: OUTER)? JOIN$/i', $join_cond[0] ) ) {
840  $options['FOR UPDATE'][] = $table_cond;
841  }
842  }
843  }
844  }
845 
846  return parent::selectSQLText( $table, $vars, $conds, $fname, $options, $join_conds );
847  }
848 
861  function insert( $table, $args, $fname = __METHOD__, $options = array() ) {
862  if ( !count( $args ) ) {
863  return true;
864  }
865 
866  $table = $this->tableName( $table );
867  if ( !isset( $this->numericVersion ) ) {
868  $this->getServerVersion();
869  }
870 
871  if ( !is_array( $options ) ) {
872  $options = array( $options );
873  }
874 
875  if ( isset( $args[0] ) && is_array( $args[0] ) ) {
876  $multi = true;
877  $keys = array_keys( $args[0] );
878  } else {
879  $multi = false;
880  $keys = array_keys( $args );
881  }
882 
883  // If IGNORE is set, we use savepoints to emulate mysql's behavior
884  $savepoint = null;
885  if ( in_array( 'IGNORE', $options ) ) {
886  $savepoint = new SavepointPostgres( $this, 'mw' );
887  $olde = error_reporting( 0 );
888  // For future use, we may want to track the number of actual inserts
889  // Right now, insert (all writes) simply return true/false
890  $numrowsinserted = 0;
891  }
892 
893  $sql = "INSERT INTO $table (" . implode( ',', $keys ) . ') VALUES ';
894 
895  if ( $multi ) {
896  if ( $this->numericVersion >= 8.2 && !$savepoint ) {
897  $first = true;
898  foreach ( $args as $row ) {
899  if ( $first ) {
900  $first = false;
901  } else {
902  $sql .= ',';
903  }
904  $sql .= '(' . $this->makeList( $row ) . ')';
905  }
906  $res = (bool)$this->query( $sql, $fname, $savepoint );
907  } else {
908  $res = true;
909  $origsql = $sql;
910  foreach ( $args as $row ) {
911  $tempsql = $origsql;
912  $tempsql .= '(' . $this->makeList( $row ) . ')';
913 
914  if ( $savepoint ) {
915  $savepoint->savepoint();
916  }
917 
918  $tempres = (bool)$this->query( $tempsql, $fname, $savepoint );
919 
920  if ( $savepoint ) {
921  $bar = pg_last_error();
922  if ( $bar != false ) {
923  $savepoint->rollback();
924  } else {
925  $savepoint->release();
926  $numrowsinserted++;
927  }
928  }
929 
930  // If any of them fail, we fail overall for this function call
931  // Note that this will be ignored if IGNORE is set
932  if ( !$tempres ) {
933  $res = false;
934  }
935  }
936  }
937  } else {
938  // Not multi, just a lone insert
939  if ( $savepoint ) {
940  $savepoint->savepoint();
941  }
942 
943  $sql .= '(' . $this->makeList( $args ) . ')';
944  $res = (bool)$this->query( $sql, $fname, $savepoint );
945  if ( $savepoint ) {
946  $bar = pg_last_error();
947  if ( $bar != false ) {
948  $savepoint->rollback();
949  } else {
950  $savepoint->release();
951  $numrowsinserted++;
952  }
953  }
954  }
955  if ( $savepoint ) {
956  error_reporting( $olde );
957  $savepoint->commit();
958 
959  // Set the affected row count for the whole operation
960  $this->mAffectedRows = $numrowsinserted;
961 
962  // IGNORE always returns true
963  return true;
964  }
965 
966  return $res;
967  }
968 
987  function insertSelect( $destTable, $srcTable, $varMap, $conds, $fname = __METHOD__,
988  $insertOptions = array(), $selectOptions = array() ) {
989  $destTable = $this->tableName( $destTable );
990 
991  if ( !is_array( $insertOptions ) ) {
992  $insertOptions = array( $insertOptions );
993  }
994 
995  /*
996  * If IGNORE is set, we use savepoints to emulate mysql's behavior
997  * Ignore LOW PRIORITY option, since it is MySQL-specific
998  */
999  $savepoint = null;
1000  if ( in_array( 'IGNORE', $insertOptions ) ) {
1001  $savepoint = new SavepointPostgres( $this, 'mw' );
1002  $olde = error_reporting( 0 );
1003  $numrowsinserted = 0;
1004  $savepoint->savepoint();
1005  }
1006 
1007  if ( !is_array( $selectOptions ) ) {
1008  $selectOptions = array( $selectOptions );
1009  }
1010  list( $startOpts, $useIndex, $tailOpts ) = $this->makeSelectOptions( $selectOptions );
1011  if ( is_array( $srcTable ) ) {
1012  $srcTable = implode( ',', array_map( array( &$this, 'tableName' ), $srcTable ) );
1013  } else {
1014  $srcTable = $this->tableName( $srcTable );
1015  }
1016 
1017  $sql = "INSERT INTO $destTable (" . implode( ',', array_keys( $varMap ) ) . ')' .
1018  " SELECT $startOpts " . implode( ',', $varMap ) .
1019  " FROM $srcTable $useIndex";
1020 
1021  if ( $conds != '*' ) {
1022  $sql .= ' WHERE ' . $this->makeList( $conds, LIST_AND );
1023  }
1024 
1025  $sql .= " $tailOpts";
1026 
1027  $res = (bool)$this->query( $sql, $fname, $savepoint );
1028  if ( $savepoint ) {
1029  $bar = pg_last_error();
1030  if ( $bar != false ) {
1031  $savepoint->rollback();
1032  } else {
1033  $savepoint->release();
1034  $numrowsinserted++;
1035  }
1036  error_reporting( $olde );
1037  $savepoint->commit();
1038 
1039  // Set the affected row count for the whole operation
1040  $this->mAffectedRows = $numrowsinserted;
1041 
1042  // IGNORE always returns true
1043  return true;
1044  }
1045 
1046  return $res;
1047  }
1048 
1049  function tableName( $name, $format = 'quoted' ) {
1050  # Replace reserved words with better ones
1051  switch ( $name ) {
1052  case 'user':
1053  return $this->realTableName( 'mwuser', $format );
1054  case 'text':
1055  return $this->realTableName( 'pagecontent', $format );
1056  default:
1057  return $this->realTableName( $name, $format );
1058  }
1059  }
1060 
1061  /* Don't cheat on installer */
1062  function realTableName( $name, $format = 'quoted' ) {
1063  return parent::tableName( $name, $format );
1064  }
1072  function nextSequenceValue( $seqName ) {
1073  $safeseq = str_replace( "'", "''", $seqName );
1074  $res = $this->query( "SELECT nextval('$safeseq')" );
1075  $row = $this->fetchRow( $res );
1076  $this->mInsertId = $row[0];
1077 
1078  return $this->mInsertId;
1079  }
1080 
1087  function currentSequenceValue( $seqName ) {
1088  $safeseq = str_replace( "'", "''", $seqName );
1089  $res = $this->query( "SELECT currval('$safeseq')" );
1090  $row = $this->fetchRow( $res );
1091  $currval = $row[0];
1092 
1093  return $currval;
1094  }
1095 
1096  # Returns the size of a text field, or -1 for "unlimited"
1097  function textFieldSize( $table, $field ) {
1098  $table = $this->tableName( $table );
1099  $sql = "SELECT t.typname as ftype,a.atttypmod as size
1100  FROM pg_class c, pg_attribute a, pg_type t
1101  WHERE relname='$table' AND a.attrelid=c.oid AND
1102  a.atttypid=t.oid and a.attname='$field'";
1103  $res = $this->query( $sql );
1104  $row = $this->fetchObject( $res );
1105  if ( $row->ftype == 'varchar' ) {
1106  $size = $row->size - 4;
1107  } else {
1108  $size = $row->size;
1109  }
1110 
1111  return $size;
1112  }
1113 
1114  function limitResult( $sql, $limit, $offset = false ) {
1115  return "$sql LIMIT $limit " . ( is_numeric( $offset ) ? " OFFSET {$offset} " : '' );
1116  }
1117 
1118  function wasDeadlock() {
1119  return $this->lastErrno() == '40P01';
1120  }
1121 
1122  function duplicateTableStructure( $oldName, $newName, $temporary = false, $fname = __METHOD__ ) {
1123  $newName = $this->addIdentifierQuotes( $newName );
1124  $oldName = $this->addIdentifierQuotes( $oldName );
1125 
1126  return $this->query( 'CREATE ' . ( $temporary ? 'TEMPORARY ' : '' ) . " TABLE $newName " .
1127  "(LIKE $oldName INCLUDING DEFAULTS)", $fname );
1128  }
1129 
1130  function listTables( $prefix = null, $fname = __METHOD__ ) {
1131  $eschema = $this->addQuotes( $this->getCoreSchema() );
1132  $result = $this->query( "SELECT tablename FROM pg_tables WHERE schemaname = $eschema", $fname );
1133  $endArray = array();
1134 
1135  foreach ( $result as $table ) {
1136  $vars = get_object_vars( $table );
1137  $table = array_pop( $vars );
1138  if ( !$prefix || strpos( $table, $prefix ) === 0 ) {
1139  $endArray[] = $table;
1140  }
1141  }
1142 
1143  return $endArray;
1144  }
1145 
1146  function timestamp( $ts = 0 ) {
1147  return wfTimestamp( TS_POSTGRES, $ts );
1148  }
1149 
1150  /*
1151  * Posted by cc[plus]php[at]c2se[dot]com on 25-Mar-2009 09:12
1152  * to http://www.php.net/manual/en/ref.pgsql.php
1153  *
1154  * Parsing a postgres array can be a tricky problem, he's my
1155  * take on this, it handles multi-dimensional arrays plus
1156  * escaping using a nasty regexp to determine the limits of each
1157  * data-item.
1158  *
1159  * This should really be handled by PHP PostgreSQL module
1160  *
1161  * @since 1.19
1162  * @param string $text Postgreql array returned in a text form like {a,b}
1163  * @param string $output
1164  * @param int $limit
1165  * @param int $offset
1166  * @return string
1167  */
1168  function pg_array_parse( $text, &$output, $limit = false, $offset = 1 ) {
1169  if ( false === $limit ) {
1170  $limit = strlen( $text ) - 1;
1171  $output = array();
1172  }
1173  if ( '{}' == $text ) {
1174  return $output;
1175  }
1176  do {
1177  if ( '{' != $text[$offset] ) {
1178  preg_match( "/(\\{?\"([^\"\\\\]|\\\\.)*\"|[^,{}]+)+([,}]+)/",
1179  $text, $match, 0, $offset );
1180  $offset += strlen( $match[0] );
1181  $output[] = ( '"' != $match[1][0]
1182  ? $match[1]
1183  : stripcslashes( substr( $match[1], 1, -1 ) ) );
1184  if ( '},' == $match[3] ) {
1185  return $output;
1186  }
1187  } else {
1188  $offset = $this->pg_array_parse( $text, $output, $limit, $offset + 1 );
1189  }
1190  } while ( $limit > $offset );
1191 
1192  return $output;
1193  }
1194 
1198  public function aggregateValue( $valuedata, $valuename = 'value' ) {
1199  return $valuedata;
1200  }
1205  public function getSoftwareLink() {
1206  return '[{{int:version-db-postgres-url}} PostgreSQL]';
1207  }
1208 
1216  function getCurrentSchema() {
1217  $res = $this->query( "SELECT current_schema()", __METHOD__ );
1218  $row = $this->fetchRow( $res );
1219 
1220  return $row[0];
1221  }
1222 
1233  function getSchemas() {
1234  $res = $this->query( "SELECT current_schemas(false)", __METHOD__ );
1235  $row = $this->fetchRow( $res );
1236  $schemas = array();
1237 
1238  /* PHP pgsql support does not support array type, "{a,b}" string is returned */
1239 
1240  return $this->pg_array_parse( $row[0], $schemas );
1241  }
1242 
1252  function getSearchPath() {
1253  $res = $this->query( "SHOW search_path", __METHOD__ );
1254  $row = $this->fetchRow( $res );
1255 
1256  /* PostgreSQL returns SHOW values as strings */
1257 
1258  return explode( ",", $row[0] );
1259  }
1260 
1268  function setSearchPath( $search_path ) {
1269  $this->query( "SET search_path = " . implode( ", ", $search_path ) );
1270  }
1271 
1286  function determineCoreSchema( $desiredSchema ) {
1287  $this->begin( __METHOD__ );
1288  if ( $this->schemaExists( $desiredSchema ) ) {
1289  if ( in_array( $desiredSchema, $this->getSchemas() ) ) {
1290  $this->mCoreSchema = $desiredSchema;
1291  wfDebug( "Schema \"" . $desiredSchema . "\" already in the search path\n" );
1292  } else {
1298  $search_path = $this->getSearchPath();
1299  array_unshift( $search_path,
1300  $this->addIdentifierQuotes( $desiredSchema ) );
1301  $this->setSearchPath( $search_path );
1302  $this->mCoreSchema = $desiredSchema;
1303  wfDebug( "Schema \"" . $desiredSchema . "\" added to the search path\n" );
1304  }
1305  } else {
1306  $this->mCoreSchema = $this->getCurrentSchema();
1307  wfDebug( "Schema \"" . $desiredSchema . "\" not found, using current \"" .
1308  $this->mCoreSchema . "\"\n" );
1309  }
1310  /* Commit SET otherwise it will be rollbacked on error or IGNORE SELECT */
1311  $this->commit( __METHOD__ );
1312  }
1313 
1320  function getCoreSchema() {
1322  }
1323 
1327  function getServerVersion() {
1328  if ( !isset( $this->numericVersion ) ) {
1329  $versionInfo = pg_version( $this->mConn );
1330  if ( version_compare( $versionInfo['client'], '7.4.0', 'lt' ) ) {
1331  // Old client, abort install
1332  $this->numericVersion = '7.3 or earlier';
1333  } elseif ( isset( $versionInfo['server'] ) ) {
1334  // Normal client
1335  $this->numericVersion = $versionInfo['server'];
1336  } else {
1337  // Bug 16937: broken pgsql extension from PHP<5.3
1338  $this->numericVersion = pg_parameter_status( $this->mConn, 'server_version' );
1339  }
1340  }
1341 
1342  return $this->numericVersion;
1343  }
1344 
1353  function relationExists( $table, $types, $schema = false ) {
1354  if ( !is_array( $types ) ) {
1355  $types = array( $types );
1356  }
1357  if ( !$schema ) {
1358  $schema = $this->getCoreSchema();
1359  }
1360  $table = $this->realTableName( $table, 'raw' );
1361  $etable = $this->addQuotes( $table );
1362  $eschema = $this->addQuotes( $schema );
1363  $sql = "SELECT 1 FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "
1364  . "WHERE c.relnamespace = n.oid AND c.relname = $etable AND n.nspname = $eschema "
1365  . "AND c.relkind IN ('" . implode( "','", $types ) . "')";
1366  $res = $this->query( $sql );
1367  $count = $res ? $res->numRows() : 0;
1368 
1369  return (bool)$count;
1370  }
1371 
1380  function tableExists( $table, $fname = __METHOD__, $schema = false ) {
1381  return $this->relationExists( $table, array( 'r', 'v' ), $schema );
1382  }
1383 
1384  function sequenceExists( $sequence, $schema = false ) {
1385  return $this->relationExists( $sequence, 'S', $schema );
1386  }
1387 
1388  function triggerExists( $table, $trigger ) {
1389  $q = <<<SQL
1390  SELECT 1 FROM pg_class, pg_namespace, pg_trigger
1391  WHERE relnamespace=pg_namespace.oid AND relkind='r'
1392  AND tgrelid=pg_class.oid
1393  AND nspname=%s AND relname=%s AND tgname=%s
1394 SQL;
1395  $res = $this->query(
1396  sprintf(
1397  $q,
1398  $this->addQuotes( $this->getCoreSchema() ),
1399  $this->addQuotes( $table ),
1400  $this->addQuotes( $trigger )
1401  )
1402  );
1403  if ( !$res ) {
1404  return null;
1405  }
1406  $rows = $res->numRows();
1407 
1408  return $rows;
1409  }
1410 
1411  function ruleExists( $table, $rule ) {
1412  $exists = $this->selectField( 'pg_rules', 'rulename',
1413  array(
1414  'rulename' => $rule,
1415  'tablename' => $table,
1416  'schemaname' => $this->getCoreSchema()
1417  )
1418  );
1419 
1420  return $exists === $rule;
1421  }
1422 
1423  function constraintExists( $table, $constraint ) {
1424  $sql = sprintf( "SELECT 1 FROM information_schema.table_constraints " .
1425  "WHERE constraint_schema = %s AND table_name = %s AND constraint_name = %s",
1426  $this->addQuotes( $this->getCoreSchema() ),
1427  $this->addQuotes( $table ),
1428  $this->addQuotes( $constraint )
1429  );
1430  $res = $this->query( $sql );
1431  if ( !$res ) {
1432  return null;
1433  }
1434  $rows = $res->numRows();
1435 
1436  return $rows;
1437  }
1438 
1444  function schemaExists( $schema ) {
1445  $exists = $this->selectField( '"pg_catalog"."pg_namespace"', 1,
1446  array( 'nspname' => $schema ), __METHOD__ );
1447 
1448  return (bool)$exists;
1449  }
1450 
1456  function roleExists( $roleName ) {
1457  $exists = $this->selectField( '"pg_catalog"."pg_roles"', 1,
1458  array( 'rolname' => $roleName ), __METHOD__ );
1459 
1460  return (bool)$exists;
1461  }
1462 
1463  function fieldInfo( $table, $field ) {
1464  return PostgresField::fromText( $this, $table, $field );
1465  }
1466 
1473  function fieldType( $res, $index ) {
1474  if ( $res instanceof ResultWrapper ) {
1475  $res = $res->result;
1476  }
1477 
1478  return pg_field_type( $res, $index );
1479  }
1480 
1485  function encodeBlob( $b ) {
1486  return new Blob( pg_escape_bytea( $this->mConn, $b ) );
1487  }
1488 
1489  function decodeBlob( $b ) {
1490  if ( $b instanceof Blob ) {
1491  $b = $b->fetch();
1492  }
1493 
1494  return pg_unescape_bytea( $b );
1495  }
1496 
1497  function strencode( $s ) { # Should not be called by us
1498  return pg_escape_string( $this->mConn, $s );
1499  }
1500 
1505  function addQuotes( $s ) {
1506  if ( is_null( $s ) ) {
1507  return 'NULL';
1508  } elseif ( is_bool( $s ) ) {
1509  return intval( $s );
1510  } elseif ( $s instanceof Blob ) {
1511  return "'" . $s->fetch( $s ) . "'";
1512  }
1513 
1514  return "'" . pg_escape_string( $this->mConn, $s ) . "'";
1515  }
1516 
1524  protected function replaceVars( $ins ) {
1525  $ins = parent::replaceVars( $ins );
1526 
1527  if ( $this->numericVersion >= 8.3 ) {
1528  // Thanks for not providing backwards-compatibility, 8.3
1529  $ins = preg_replace( "/to_tsvector\s*\(\s*'default'\s*,/", 'to_tsvector(', $ins );
1530  }
1531 
1532  if ( $this->numericVersion <= 8.1 ) { // Our minimum version
1533  $ins = str_replace( 'USING gin', 'USING gist', $ins );
1534  }
1535 
1536  return $ins;
1537  }
1538 
1546  function makeSelectOptions( $options ) {
1547  $preLimitTail = $postLimitTail = '';
1548  $startOpts = $useIndex = '';
1549 
1550  $noKeyOptions = array();
1551  foreach ( $options as $key => $option ) {
1552  if ( is_numeric( $key ) ) {
1553  $noKeyOptions[$option] = true;
1554  }
1555  }
1557  $preLimitTail .= $this->makeGroupByWithHaving( $options );
1558 
1559  $preLimitTail .= $this->makeOrderBy( $options );
1561  //if ( isset( $options['LIMIT'] ) ) {
1562  // $tailOpts .= $this->limitResult( '', $options['LIMIT'],
1563  // isset( $options['OFFSET'] ) ? $options['OFFSET']
1564  // : false );
1565  //}
1566 
1567  if ( isset( $options['FOR UPDATE'] ) ) {
1568  $postLimitTail .= ' FOR UPDATE OF ' . implode( ', ', $options['FOR UPDATE'] );
1569  } elseif ( isset( $noKeyOptions['FOR UPDATE'] ) ) {
1570  $postLimitTail .= ' FOR UPDATE';
1571  }
1573  if ( isset( $noKeyOptions['DISTINCT'] ) || isset( $noKeyOptions['DISTINCTROW'] ) ) {
1574  $startOpts .= 'DISTINCT';
1575  }
1576 
1577  return array( $startOpts, $useIndex, $preLimitTail, $postLimitTail );
1578  }
1579 
1580  function getDBname() {
1581  return $this->mDBname;
1582  }
1583 
1584  function getServer() {
1585  return $this->mServer;
1586  }
1587 
1588  function buildConcat( $stringList ) {
1589  return implode( ' || ', $stringList );
1590  }
1591 
1592  public function buildGroupConcatField(
1593  $delimiter, $table, $field, $conds = '', $options = array(), $join_conds = array()
1594  ) {
1595  $fld = "array_to_string(array_agg($field)," . $this->addQuotes( $delimiter ) . ')';
1596 
1597  return '(' . $this->selectSQLText( $table, $fld, $conds, null, array(), $join_conds ) . ')';
1598  }
1599 
1600  public function getSearchEngine() {
1601  return 'SearchPostgres';
1602  }
1603 
1604  public function streamStatementEnd( &$sql, &$newLine ) {
1605  # Allow dollar quoting for function declarations
1606  if ( substr( $newLine, 0, 4 ) == '$mw$' ) {
1607  if ( $this->delimiter ) {
1608  $this->delimiter = false;
1609  } else {
1610  $this->delimiter = ';';
1611  }
1612  }
1613 
1614  return parent::streamStatementEnd( $sql, $newLine );
1615  }
1616 
1626  public function lockIsFree( $lockName, $method ) {
1627  $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
1628  $result = $this->query( "SELECT (CASE(pg_try_advisory_lock($key))
1629  WHEN 'f' THEN 'f' ELSE pg_advisory_unlock($key) END) AS lockstatus", $method );
1630  $row = $this->fetchObject( $result );
1631 
1632  return ( $row->lockstatus === 't' );
1633  }
1642  public function lock( $lockName, $method, $timeout = 5 ) {
1643  $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
1644  for ( $attempts = 1; $attempts <= $timeout; ++$attempts ) {
1645  $result = $this->query(
1646  "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
1647  $row = $this->fetchObject( $result );
1648  if ( $row->lockstatus === 't' ) {
1649  return true;
1650  } else {
1651  sleep( 1 );
1652  }
1653  }
1654  wfDebug( __METHOD__ . " failed to acquire lock\n" );
1655 
1656  return false;
1657  }
1658 
1666  public function unlock( $lockName, $method ) {
1667  $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
1668  $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
1669  $row = $this->fetchObject( $result );
1670 
1671  return ( $row->lockstatus === 't' );
1672  }
1673 
1678  private function bigintFromLockName( $lockName ) {
1679  return wfBaseConvert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
1680  }
1681 } // 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:1321
DatabasePostgres\fieldInfo
fieldInfo( $table, $field)
mysql_fetch_field() wrapper Returns false if the field doesn't exist
Definition: DatabasePostgres.php:1431
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:829
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:955
DatabasePostgres\getSchemas
getSchemas()
Return list of schemas which are accessible without schema name This is list does not contain magic k...
Definition: DatabasePostgres.php:1201
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:1086
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:1184
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:1492
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:1098
DatabasePostgres\currentSequenceValue
currentSequenceValue( $seqName)
Return the current value of a sequence.
Definition: DatabasePostgres.php:1055
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:1166
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:1556
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:1610
$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:1236
$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:798
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:1568
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:1634
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:1295
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:1514
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:1560
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:1552
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:1065
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:1173
$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:1457
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:1082
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:1114
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:1220
DatabasePostgres\tableName
tableName( $name, $format='quoted')
Format a table name ready for use in constructing an SQL query.
Definition: DatabasePostgres.php:1017
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:1348
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:1473
$ok
$ok
Definition: UtfNormalTest.php:71
DatabasePostgres\lockIsFree
lockIsFree( $lockName, $method)
Check to see if a named lock is available.
Definition: DatabasePostgres.php:1594
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:1572
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:1040
DatabasePostgres\sequenceExists
sequenceExists( $sequence, $schema=false)
Definition: DatabasePostgres.php:1352
$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:1030
DatabasePostgres\pg_array_parse
pg_array_parse( $text, &$output, $limit=false, $offset=1)
Definition: DatabasePostgres.php:1136
DatabasePostgres\triggerExists
triggerExists( $table, $trigger)
Definition: DatabasePostgres.php:1356
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:1424
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:1412
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:1441
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:1453
$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:3368
DatabasePostgres\ruleExists
ruleExists( $table, $rule)
Definition: DatabasePostgres.php:1379
$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:1646
$keys
$keys
Definition: testCompression.php:63
DatabasePostgres\getCoreSchema
getCoreSchema()
Return schema name fore core MediaWiki tables.
Definition: DatabasePostgres.php:1288
DatabasePostgres\getDBname
getDBname()
Get the current DB name.
Definition: DatabasePostgres.php:1548
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:1090
$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:1465
$res
$res
Definition: database.txt:21
SavepointPostgres\commit
commit()
Definition: DatabasePostgres.php:221
DatabasePostgres\constraintExists
constraintExists( $table, $constraint)
Definition: DatabasePostgres.php:1391
DatabasePostgres\determineCoreSchema
determineCoreSchema( $desiredSchema)
Determine default schema for MediaWiki core Adjust this session schema search path if desired schema ...
Definition: DatabasePostgres.php:1254
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