jenkins-bot has submitted this change and it was merged.

Change subject: Fix all db subclasses sharing a PDO
......................................................................


Fix all db subclasses sharing a PDO

WTF PHP, even static::$thing refers to the same object always?
Even this gets a single shared instance:
  $klass = get_called_class();
  $db = $klass::$db

We need this to re-apply change I61ef044899ee on deployment, where
it's currently reverted.

Change-Id: Ic770319c8d1f9812e980e08fd833cdbee1bab4d6
---
M Core/DataStores/SmashPigDatabase.php
M Tests/DamagedDatabaseTest.php
A Tests/SmashPigDatabaseTest.php
M Tests/TestingDatabase.php
4 files changed, 73 insertions(+), 14 deletions(-)

Approvals:
  Cdentinger: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/Core/DataStores/SmashPigDatabase.php 
b/Core/DataStores/SmashPigDatabase.php
index 48f78b4..ad8c9b7 100644
--- a/Core/DataStores/SmashPigDatabase.php
+++ b/Core/DataStores/SmashPigDatabase.php
@@ -7,16 +7,23 @@
 abstract class SmashPigDatabase {
 
        /**
-        * @var PDO
+        * @var array
+        * key is concrete class name, value is a backing PDO object
         * We do the silly singleton thing for convenient testing with in-memory
         * databases that would otherwise not be shared between components.
+        *
+        * Ideally, this would be a scalar variable holding a single PDO object
+        * for each concrete subclass. Unfortunately, in PHP the static member
+        * variable is shared between all subclasses of the class that declares
+        * it, even in an abstract class like this one. See
+        * 
http://stackoverflow.com/questions/11417681/static-properties-on-base-class-and-inheritance#11418607
         */
-       protected static $db;
+       protected static $dbs = array();
 
        protected function __construct() {
                $config = Context::get()->getConfiguration();
-               if ( !static::$db ) {
-                       static::$db = $config->object( $this->getConfigKey() );
+               if ( !$this->getDatabase() ) {
+                       $this->setDatabase( $config->object( 
$this->getConfigKey() ) );
                }
        }
 
@@ -25,10 +32,19 @@
        }
 
        /**
-        * @return PDO
+        * @return PDO|null
         */
        public function getDatabase() {
-               return static::$db;
+               $className = get_called_class();
+               if ( isset ( self::$dbs[$className] ) ) {
+                       return self::$dbs[$className];
+               }
+               return null;
+       }
+
+       protected function setDatabase( PDO $db ) {
+               $className = get_called_class();
+               self::$dbs[$className] = $db;
        }
 
        public function createTable() {
diff --git a/Tests/DamagedDatabaseTest.php b/Tests/DamagedDatabaseTest.php
index db03227..705ddad 100644
--- a/Tests/DamagedDatabaseTest.php
+++ b/Tests/DamagedDatabaseTest.php
@@ -22,12 +22,7 @@
        }
 
        public function tearDown() {
-               // Reset PDO static member
-               $klass = new \ReflectionClass( 
'SmashPig\Core\DataStores\DamagedDatabase' );
-               $dbProperty = $klass->getProperty( 'db' );
-               $dbProperty->setAccessible( true );
-               $dbProperty->setValue( null );
-
+               TestingDatabase::clearStatics( $this->db );
                parent::tearDown();
        }
 
diff --git a/Tests/SmashPigDatabaseTest.php b/Tests/SmashPigDatabaseTest.php
new file mode 100644
index 0000000..118b897
--- /dev/null
+++ b/Tests/SmashPigDatabaseTest.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace SmashPig\Tests;
+
+use SmashPig\Core\Context;
+use SmashPig\Core\DataStores\PaymentsInitialDatabase;
+use SmashPig\Core\DataStores\PendingDatabase;
+
+class SmashPigDatabaseTest extends BaseSmashPigUnitTestCase {
+
+       /**
+        * @var PendingDatabase
+        */
+       protected $pendingDb;
+
+       /**
+        * @var PaymentsInitialDatabase
+        */
+       protected $paymentsInitialDb;
+
+       public function setUp() {
+               parent::setUp();
+               $config = SmashPigDatabaseTestConfiguration::instance();
+               Context::initWithLogger( $config );
+
+               $this->pendingDb = PendingDatabase::get();
+               $this->pendingDb->createTable();
+               $this->paymentsInitialDb = PaymentsInitialDatabase::get();
+               $this->paymentsInitialDb->createTable();
+       }
+
+       public function tearDown() {
+               TestingDatabase::clearStatics( $this->paymentsInitialDb );
+               TestingDatabase::clearStatics( $this->pendingDb );
+
+               parent::tearDown();
+       }
+
+       public function testDifferentDatabases() {
+               $pendingPdo = $this->pendingDb->getDatabase();
+               $initPdo = $this->paymentsInitialDb->getDatabase();
+               $this->assertNotEquals(
+                       spl_object_hash( $pendingPdo ),
+                       spl_object_hash( $initPdo ),
+                       'Pending and paymentsInit databases share the same PDO'
+               );
+       }
+}
diff --git a/Tests/TestingDatabase.php b/Tests/TestingDatabase.php
index 6173a22..48e0e87 100644
--- a/Tests/TestingDatabase.php
+++ b/Tests/TestingDatabase.php
@@ -10,8 +10,8 @@
         */
        public static function clearStatics( $classish ) {
                $klass = new \ReflectionClass( $classish );
-               $dbProperty = $klass->getProperty( 'db' );
+               $dbProperty = $klass->getProperty( 'dbs' );
                $dbProperty->setAccessible( true );
-               $dbProperty->setValue( null );
+               $dbProperty->setValue( array() );
        }
 }

-- 
To view, visit https://gerrit.wikimedia.org/r/317277
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic770319c8d1f9812e980e08fd833cdbee1bab4d6
Gerrit-PatchSet: 3
Gerrit-Project: wikimedia/fundraising/SmashPig
Gerrit-Branch: master
Gerrit-Owner: Ejegg <eeggles...@wikimedia.org>
Gerrit-Reviewer: Awight <awi...@wikimedia.org>
Gerrit-Reviewer: Cdentinger <cdentin...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to