fix some spacing
[lhc/web/wiklou.git] / includes / db / DatabasePostgres.php
index 86b8e8a..6f7d1fa 100644 (file)
@@ -393,6 +393,9 @@ class DatabasePostgres extends DatabaseBase {
                $this->query( "SET datestyle = 'ISO, YMD'", __METHOD__ );
                $this->query( "SET timezone = 'GMT'", __METHOD__ );
                $this->query( "SET standard_conforming_strings = on", __METHOD__ );
+               if ( $this->getServerVersion() >= 9.0 ) {
+                       $this->query( "SET bytea_output = 'escape'", __METHOD__ ); // PHP bug 53127
+               }
 
                global $wgDBmwschema;
                $this->determineCoreSchema( $wgDBmwschema );
@@ -479,7 +482,6 @@ class DatabasePostgres extends DatabaseBase {
                parent::reportQueryError( $error, $errno, $sql, $fname, false );
        }
 
-
        function queryIgnore( $sql, $fname = 'DatabasePostgres::queryIgnore' ) {
                return $this->query( $sql, $fname, true );
        }
@@ -700,7 +702,6 @@ __INDEXATTR__;
                return $a;
        }
 
-
        function indexUnique( $table, $index, $fname = 'DatabasePostgres::indexUnique' ) {
                $sql = "SELECT indexname FROM pg_indexes WHERE tablename='{$table}'".
                        " AND indexdef LIKE 'CREATE UNIQUE%(" .
@@ -1059,7 +1060,6 @@ __INDEXATTR__;
                return '[http://www.postgresql.org/ PostgreSQL]';
        }
 
-
        /**
         * Return current schema (executes SELECT current_schema())
         * Needs transaction
@@ -1436,4 +1436,65 @@ SQL;
                }
                return parent::streamStatementEnd( $sql, $newLine );
        }
+
+       /**
+        * Check to see if a named lock is available. This is non-blocking.
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        *
+        * @param $lockName String: name of lock to poll
+        * @param $method String: name of method calling us
+        * @return Boolean
+        * @since 1.20
+        */
+       public function lockIsFree( $lockName, $method ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               $result = $this->query( "SELECT (CASE(pg_try_advisory_lock($key))
+                       WHEN 'f' THEN 'f' ELSE pg_advisory_unlock($key) END) AS lockstatus", $method );
+               $row = $this->fetchObject( $result );
+               return ( $row->lockstatus === 't' );
+       }
+
+       /**
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        * @param $lockName string
+        * @param $method string
+        * @param $timeout int
+        * @return bool
+        */
+       public function lock( $lockName, $method, $timeout = 5 ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               for ( $attempts = 1; $attempts <= $timeout; ++$attempts ) {
+                       $result = $this->query(
+                               "SELECT pg_try_advisory_lock($key) AS lockstatus", $method );
+                       $row = $this->fetchObject( $result );
+                       if ( $row->lockstatus === 't' ) {
+                               return true;
+                       } else {
+                               sleep( 1 );
+                       }
+               }
+               wfDebug( __METHOD__." failed to acquire lock\n" );
+               return false;
+       }
+
+       /**
+        * See http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKSFROM PG DOCS: http://www.postgresql.org/docs/8.2/static/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS
+        * @param $lockName string
+        * @param $method string
+        * @return bool
+        */
+       public function unlock( $lockName, $method ) {
+               $key = $this->addQuotes( $this->bigintFromLockName( $lockName ) );
+               $result = $this->query( "SELECT pg_advisory_unlock($key) as lockstatus", $method );
+               $row = $this->fetchObject( $result );
+               return ( $row->lockstatus === 't' );
+       }
+
+       /**
+        * @param string $lockName
+        * @return string Integer
+        */
+       private function bigintFromLockName( $lockName ) {
+               return wfBaseConvert( substr( sha1( $lockName ), 0, 15 ), 16, 10 );
+       }
 } // end DatabasePostgres class