فهرست منبع

Merge branch 'implement-mongo-client'

* implement-mongo-client:
  Throw a bunch of exceptions in Mongo class
  Minor code cleanup
  Report correct state in getHosts()
  implement MongoClient
Andreas Braun 10 سال پیش
والد
کامیت
885f699530
4فایلهای تغییر یافته به همراه176 افزوده شده و 65 حذف شده
  1. 5 0
      README.md
  2. 105 56
      lib/Mongo/Mongo.php
  3. 50 9
      lib/Mongo/MongoClient.php
  4. 16 0
      tests/Alcaeus/MongoDbAdapter/MongoClientTest.php

+ 5 - 0
README.md

@@ -21,3 +21,8 @@ The preferred method of installing this library is with
 root:
 
     $ composer require "alcaeus/mongo-php-adapter=dev-master"
+
+# Known issues
+ - The [Mongo](https://secure.php.net/manual/en/class.mongo.php) class is
+ deprecated and was not implemented in this library. If you are still using it
+ please update your code to use the new classes.

+ 105 - 56
lib/Mongo/Mongo.php

@@ -21,108 +21,133 @@
  * Relying on this feature is highly discouraged. Please use MongoClient instead.
  * @see MongoClient
  */
-class Mongo extends MongoClient {
+class Mongo extends MongoClient
+{
+    /**
+     * Dummy constructor to throw an exception
+     */
+    public function __construct()
+    {
+        $this->notImplemented();
+    }
+
     /**
-     * @deprecated This feature has been DEPRECATED as of version 1.2.3. Relying on this feature is highly discouraged. Please use MongoPool::getSize() instead.
-     * (PECL mongo &gt;= 1.2.0)<br/>
      * Get pool size for connection pools
+     *
      * @link http://php.net/manual/en/mongo.getpoolsize.php
      * @return int Returns the current pool size.
+     *
+     * @deprecated This feature has been DEPRECATED as of version 1.2.3. Relying on this feature is highly discouraged. Please use MongoPool::getSize() instead.
      */
-    public function getPoolSize() {}
+    public function getPoolSize()
+    {
+        $this->notImplemented();
+    }
+
     /**
-     * (PECL mongo &gt;= 1.1.0)<br/>
      * Returns the address being used by this for slaveOkay reads
+     *
      * @link http://php.net/manual/en/mongo.getslave.php
-     * @return bool <p>The address of the secondary this connection is using for reads.
-     * </p>
-     * <p>
-     * This returns <b>NULL</b> if this is not connected to a replica set or not yet
+     * @return bool The address of the secondary this connection is using for
+     * reads. This returns NULL if this is not connected to a replica set or not yet
      * initialized.
-     * </p>
      */
-    public function getSlave() {}
+    public function getSlave()
+    {
+        $this->notImplemented();
+    }
+
     /**
-     * (PECL mongo &gt;= 1.1.0)<br/>
      * Get slaveOkay setting for this connection
+     *
      * @link http://php.net/manual/en/mongo.getslaveokay.php
      * @return bool Returns the value of slaveOkay for this instance.
      */
-    public function getSlaveOkay() {}
+    public function getSlaveOkay()
+    {
+        $this->notImplemented();
+    }
+
     /**
      * Connects to paired database server
-     * @deprecated Pass a string of the form "mongodb://server1,server2" to the constructor instead of using this method.
+     *
      * @link http://www.php.net/manual/en/mongo.pairconnect.php
      * @throws MongoConnectionException
      * @return boolean
+     *
+     * @deprecated Pass a string of the form "mongodb://server1,server2" to the constructor instead of using this method.
      */
-    public function pairConnect() {}
+    public function pairConnect()
+    {
+        $this->notImplemented();
+    }
 
     /**
-     * (PECL mongo &gt;= 1.2.0)<br/>
-     * @deprecated This feature has been DEPRECATED as of version 1.2.3. Relying on this feature is highly discouraged. Please use MongoPool::info() instead.
      * Returns information about all connection pools.
-     * @link http://php.net/manual/en/mongo.pooldebug.php
-     * @return array  Each connection pool has an identifier, which starts with the host. For each pool, this function shows the following fields:
-     * <p><b>in use</b></p>
-     * <p>The number of connections currently being used by MongoClient instances.
-     * in pool
-     * The number of connections currently in the pool (not being used).</p>
-     * <p><b>remaining</b></p>
-     *
-     * <p>The number of connections that could be created by this pool. For example, suppose a pool had 5 connections remaining and 3 connections in the pool. We could create 8 new instances of MongoClient before we exhausted this pool (assuming no instances of MongoClient went out of scope, returning their connections to the pool).
-     *
-     * A negative number means that this pool will spawn unlimited connections.
-     *
-     * Before a pool is created, you can change the max number of connections by calling Mongo::setPoolSize(). Once a pool is showing up in the output of this function, its size cannot be changed.</p>
-     * <p><b>timeout</b></p>
-     *
-     * <p>The socket timeout for connections in this pool. This is how long connections in this pool will attempt to connect to a server before giving up.</p>
      *
+     * @link http://php.net/manual/en/mongo.pooldebug.php
+     * @return array
+     * @deprecated This feature has been DEPRECATED as of version 1.2.3. Relying on this feature is highly discouraged. Please use MongoPool::info() instead.
      */
-    public function poolDebug() {}
+    public function poolDebug()
+    {
+        $this->notImplemented();
+    }
 
     /**
-     * (PECL mongo &gt;= 1.1.0)<br/>
      * Change slaveOkay setting for this connection
+     *
      * @link http://php.net/manual/en/mongo.setslaveokay.php
-     * @param bool $ok [optional] <p class="para">
-     * If reads should be sent to secondary members of a replica set for all
-     * possible queries using this {@see MongoClient} instance.
-     * </p>
+     * @param bool $ok
      * @return bool returns the former value of slaveOkay for this instance.
      */
-    public function setSlaveOkay ($ok) {}
+    public function setSlaveOkay ($ok)
+    {
+        $this->notImplemented();
+    }
+
     /**
-     * @deprecated Relying on this feature is highly discouraged. Please use MongoPool::setSize() instead.
-     *(PECL mongo &gt;= 1.2.0)<br/>
      * Set the size for future connection pools.
+     *
      * @link http://php.net/manual/en/mongo.setpoolsize.php
      * @param $size <p>The max number of connections future pools will be able to create. Negative numbers mean that the pool will spawn an infinite number of connections.</p>
      * @return bool Returns the former value of pool size.
+     * @deprecated Relying on this feature is highly discouraged. Please use MongoPool::setSize() instead.
      */
-    public function setPoolSize($size) {}
+    public function setPoolSize($size)
+    {
+        $this->notImplemented();
+    }
+
     /**
      * Creates a persistent connection with a database server
+     *
      * @link http://www.php.net/manual/en/mongo.persistconnect.php
-     * @deprecated Pass array("persist" => $id) to the constructor instead of using this method.
      * @param string $username A username used to identify the connection.
      * @param string $password A password used to identify the connection.
      * @throws MongoConnectionException
      * @return boolean If the connection was successful.
+     * @deprecated Pass array("persist" => $id) to the constructor instead of using this method.
      */
-    public function persistConnect($username = "", $password = "") {}
+    public function persistConnect($username = "", $password = "")
+    {
+        $this->notImplemented();
+    }
 
     /**
      * Creates a persistent connection with paired database servers
-     * @deprecated Pass "mongodb://server1,server2" and array("persist" => $id) to the constructor instead of using this method.
+     *
      * @link http://www.php.net/manual/en/mongo.pairpersistconnect.php
      * @param string $username A username used to identify the connection.
      * @param string $password A password used to identify the connection.
      * @throws MongoConnectionException
      * @return boolean If the connection was successful.
+     * @deprecated Pass "mongodb://server1,server2" and array("persist" => $id) to the constructor instead of using this method.
      */
-    public function pairPersistConnect($username = "", $password = "") {}
+    public function pairPersistConnect($username = "", $password = "")
+    {
+        $this->notImplemented();
+    }
 
     /**
      * Connects with a database server
@@ -131,37 +156,61 @@ class Mongo extends MongoClient {
      * @throws MongoConnectionException
      * @return boolean If the connection was successful.
      */
-    protected function connectUtil() {}
+    protected function connectUtil()
+    {
+        $this->notImplemented();
+    }
 
     /**
      * Check if there was an error on the most recent db operation performed
-     * @deprecated Use MongoDB::lastError() instead.
+     *
      * @link http://www.php.net/manual/en/mongo.lasterror.php
      * @return array|null Returns the error, if there was one, or NULL.
+     * @deprecated Use MongoDB::lastError() instead.
      */
-    public function lastError() {}
+    public function lastError()
+    {
+        $this->notImplemented();
+    }
 
     /**
      * Checks for the last error thrown during a database operation
-     * @deprecated Use MongoDB::prevError() instead.
+     *
      * @link http://www.php.net/manual/en/mongo.preverror.php
      * @return array Returns the error and the number of operations ago it occurred.
+     * @deprecated Use MongoDB::prevError() instead.
      */
-    public function prevError() {}
+    public function prevError()
+    {
+        $this->notImplemented();
+    }
 
     /**
      * Clears any flagged errors on the connection
-     * @deprecated Use MongoDB::resetError() instead.
+     *
      * @link http://www.php.net/manual/en/mongo.reseterror.php
      * @return array Returns the database response.
+     * @deprecated Use MongoDB::resetError() instead.
      */
-    public function resetError() {}
+    public function resetError()
+    {
+        $this->notImplemented();
+    }
 
     /**
      * Creates a database error on the database.
-     * @deprecated Use MongoDB::forceError() instead.
+     *
      * @link http://www.php.net/manual/en/mongo.forceerror.php
      * @return boolean The database response.
+     * @deprecated Use MongoDB::forceError() instead.
      */
-    public function forceError() {}
+    public function forceError()
+    {
+        $this->notImplemented();
+    }
+
+    protected function notImplemented()
+    {
+        throw new \Exception('The Mongo class is deprecated and not supported through mongo-php-adapter');
+    }
 }

+ 50 - 9
lib/Mongo/MongoClient.php

@@ -62,6 +62,11 @@ class MongoClient
     private $client;
 
     /**
+     * @var \MongoDB\Driver\Manager
+     */
+    private $manager;
+
+    /**
      * Creates a new database connection object
      *
      * @link http://php.net/manual/en/mongo.construct.php
@@ -70,7 +75,7 @@ class MongoClient
      * @param array $driverOptions An array of options for the MongoDB driver.
      * @throws MongoConnectionException
      */
-    public function __construct($server = 'default', array $options = ["connect" => true], array $driverOptions = [])
+    public function __construct($server = 'default', array $options = ['connect' => true], array $driverOptions = [])
     {
         if ($server === 'default') {
             $server = 'mongodb://' . self::DEFAULT_HOST . ':' . self::DEFAULT_PORT;
@@ -78,6 +83,8 @@ class MongoClient
 
         $this->server = $server;
         $this->client = new Client($server, $options, $driverOptions);
+        $info = $this->client->__debugInfo();
+        $this->manager = $info['manager'];
 
         if (isset($options['connect']) && $options['connect']) {
             $this->connect();
@@ -172,23 +179,48 @@ class MongoClient
      */
     public function getHosts()
     {
-        return [];
+        $this->forceConnect();
+
+        $servers = [];
+        foreach ($this->manager->getServers() as $server) {
+            $key = sprintf('%s:%d', $server->getHost(), $server->getPort());
+            $info = $server->getInfo();
+
+            switch ($server->getType()) {
+                case \MongoDB\Driver\Server::TYPE_RS_PRIMARY:
+                    $state = 1;
+                    break;
+                case \MongoDB\Driver\Server::TYPE_RS_SECONDARY:
+                    $state = 2;
+                    break;
+                default:
+                    $state = 0;
+            }
+
+            $servers[$key] = [
+                'host' => $server->getHost(),
+                'port' => $server->getPort(),
+                'health' => (int) $info['ok'],
+                'state' => $state,
+                'ping' => $server->getLatency(),
+                'lastPing' => null,
+            ];
+        }
+
+        return $servers;
     }
 
     /**
      * Kills a specific cursor on the server
      *
      * @link http://www.php.net/manual/en/mongoclient.killcursor.php
-     * @param string $server_hash The server hash that has the cursor. This can be obtained through
-     * {@link http://www.php.net/manual/en/mongocursor.info.php MongoCursor::info()}.
-     * @param int|MongoInt64 $id The ID of the cursor to kill. You can either supply an {@link http://www.php.net/manual/en/language.types.integer.php int}
-     * containing the 64 bit cursor ID, or an object of the
-     * {@link http://www.php.net/manual/en/class.mongoint64.php MongoInt64} class. The latter is necessary on 32
-     * bit platforms (and Windows).
+     * @param string $server_hash The server hash that has the cursor.
+     * @param int|MongoInt64 $id The ID of the cursor to kill.
+     * @return bool
      */
     public function killCursor($server_hash , $id)
     {
-
+        throw new \Exception('Not implemented');
     }
 
     /**
@@ -267,5 +299,14 @@ class MongoClient
     {
         return $this->server;
     }
+
+    /**
+     * Forces a connection by executing the ping command
+     */
+    private function forceConnect()
+    {
+        $command = new \MongoDB\Driver\Command(['ping' => 1]);
+        $this->manager->executeCommand('db', $command);
+    }
 }
 

+ 16 - 0
tests/Alcaeus/MongoDbAdapter/MongoClientTest.php

@@ -46,6 +46,22 @@ class MongoClientTest extends TestCase
         $this->assertSame('mongo-php-adapter.test', (string) $collection);
     }
 
+    public function testGetHosts()
+    {
+        $client = $this->getClient();
+        $this->assertArraySubset(
+            [
+                'localhost:27017' => [
+                    'host' => 'localhost',
+                    'port' => 27017,
+                    'health' => 1,
+                    'state' => 0,
+                ],
+            ],
+            $client->getHosts()
+        );
+    }
+
     public function testReadPreference()
     {
         $client = $this->getClient();