Bladeren bron

Add helpers for readPreference and writeConcern

Andreas Braun 10 jaren geleden
bovenliggende
commit
64434c3dc6

+ 5 - 69
lib/Alcaeus/MongoDbAdapter/AbstractCursor.php

@@ -14,15 +14,18 @@
  */
 
 namespace Alcaeus\MongoDbAdapter;
+
+use Alcaeus\MongoDbAdapter\Helper\ReadPreference;
 use MongoDB\Collection;
 use MongoDB\Driver\Cursor;
-use MongoDB\Driver\ReadPreference;
 
 /**
  * @internal
  */
 abstract class AbstractCursor
 {
+    use ReadPreference;
+
     /**
      * @var int
      */
@@ -67,11 +70,6 @@ abstract class AbstractCursor
     ];
 
     /**
-     * @var array
-     */
-    protected $readPreference = [];
-
-    /**
      * @return Cursor
      */
     abstract protected function ensureCursor();
@@ -188,16 +186,6 @@ abstract class AbstractCursor
     }
 
     /**
-     * Get the read preference for this query
-     * @link http://www.php.net/manual/en/mongocursor.getreadpreference.php
-     * @return array
-     */
-    public function getReadPreference()
-    {
-        return $this->readPreference;
-    }
-
-    /**
      * @return array
      */
     public function info()
@@ -213,27 +201,7 @@ abstract class AbstractCursor
      */
     public function setReadPreference($readPreference, $tags = null)
     {
-        $availableReadPreferences = [
-            \MongoClient::RP_PRIMARY,
-            \MongoClient::RP_PRIMARY_PREFERRED,
-            \MongoClient::RP_SECONDARY,
-            \MongoClient::RP_SECONDARY_PREFERRED,
-            \MongoClient::RP_NEAREST
-        ];
-        if (! in_array($readPreference, $availableReadPreferences)) {
-            trigger_error("The value '$readPreference' is not valid as read preference type", E_WARNING);
-            return $this;
-        }
-
-        if ($readPreference == \MongoClient::RP_PRIMARY && count($tags)) {
-            trigger_error("You can't use read preference tags with a read preference of PRIMARY", E_WARNING);
-            return $this;
-        }
-
-        $this->readPreference = [
-            'type' => $readPreference,
-            'tagsets' => $tags
-        ];
+        $this->setReadPreferenceFromParameters($readPreference, $tags);
 
         return $this;
     }
@@ -278,38 +246,6 @@ abstract class AbstractCursor
     }
 
     /**
-     * @return ReadPreference|null
-     */
-    protected function convertReadPreference()
-    {
-        $type = array_key_exists('type', $this->readPreference) ? $this->readPreference['type'] : null;
-        if ($type === null) {
-            return null;
-        }
-
-        switch ($type) {
-            case \MongoClient::RP_PRIMARY_PREFERRED:
-                $mode = ReadPreference::RP_PRIMARY_PREFERRED;
-                break;
-            case \MongoClient::RP_SECONDARY:
-                $mode = ReadPreference::RP_SECONDARY;
-                break;
-            case \MongoClient::RP_SECONDARY_PREFERRED:
-                $mode = ReadPreference::RP_SECONDARY_PREFERRED;
-                break;
-            case \MongoClient::RP_NEAREST:
-                $mode = ReadPreference::RP_NEAREST;
-                break;
-            default:
-                $mode = ReadPreference::RP_PRIMARY;
-        }
-
-        $tagSets = array_key_exists('tagsets', $this->readPreference) ? $this->readPreference['tagsets'] : [];
-
-        return new ReadPreference($mode, $tagSets);
-    }
-
-    /**
      * @return \IteratorIterator
      */
     protected function ensureIterator()

+ 120 - 0
lib/Alcaeus/MongoDbAdapter/Helper/ReadPreference.php

@@ -0,0 +1,120 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Alcaeus\MongoDbAdapter\Helper;
+
+/**
+ * @internal
+ */
+trait ReadPreference
+{
+    /**
+     * @var \MongoDB\Driver\ReadPreference
+     */
+    protected $readPreference;
+
+    /**
+     * @param string $readPreference
+     * @param array $tags
+     * @return bool
+     */
+    abstract public function setReadPreference($readPreference, $tags = null);
+
+    /**
+     * @return array
+     */
+    public function getReadPreference()
+    {
+        if ($this->readPreference === null) {
+            $this->readPreference = new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_PRIMARY);
+        }
+
+        $mode = $this->readPreference->getMode();
+
+        switch ($mode) {
+            case \MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED:
+                $type = \MongoClient::RP_PRIMARY_PREFERRED;
+                break;
+            case \MongoDB\Driver\ReadPreference::RP_SECONDARY:
+                $type = \MongoClient::RP_SECONDARY;
+                break;
+            case \MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED:
+                $type = \MongoClient::RP_SECONDARY_PREFERRED;
+                break;
+            case \MongoDB\Driver\ReadPreference::RP_NEAREST:
+                $type = \MongoClient::RP_NEAREST;
+                break;
+            default:
+                $type = \MongoClient::RP_PRIMARY;
+        }
+
+        $readPreference = ['type' => $type];
+        if ($this->readPreference->getTagSets() !== null && $this->readPreference->getTagSets() !== []) {
+            $readPreference['tagsets'] = $this->readPreference->getTagSets();
+        }
+
+        return $readPreference;
+    }
+
+    /**
+     * @param string $readPreference
+     * @param array $tags
+     * @return bool
+     */
+    protected function setReadPreferenceFromParameters($readPreference, $tags = null)
+    {
+        switch ($readPreference) {
+            case \MongoClient::RP_PRIMARY:
+                $mode = \MongoDB\Driver\ReadPreference::RP_PRIMARY;
+                break;
+            case \MongoClient::RP_PRIMARY_PREFERRED:
+                $mode = \MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED;
+                break;
+            case \MongoClient::RP_SECONDARY:
+                $mode = \MongoDB\Driver\ReadPreference::RP_SECONDARY;
+                break;
+            case \MongoClient::RP_SECONDARY_PREFERRED:
+                $mode = \MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED;
+                break;
+            case \MongoClient::RP_NEAREST:
+                $mode = \MongoDB\Driver\ReadPreference::RP_NEAREST;
+                break;
+            default:
+                trigger_error("The value '$readPreference' is not valid as read preference type", E_WARNING);
+                return false;
+        }
+
+        if ($readPreference == \MongoClient::RP_PRIMARY && count($tags)) {
+            trigger_error("You can't use read preference tags with a read preference of PRIMARY", E_WARNING);
+            return false;
+        }
+
+        $this->readPreference = new \MongoDB\Driver\ReadPreference($mode, $tags);
+
+        return true;
+    }
+
+    /**
+     * @param array $readPreferenceArray
+     * @return bool
+     */
+    protected function setReadPreferenceFromArray($readPreferenceArray)
+    {
+        $readPreference = $readPreferenceArray['type'];
+        $tags = isset($readPreferenceArray['tagsets']) ? $readPreferenceArray['tagsets'] : [];
+
+        return $this->setReadPreferenceFromParameters($readPreference, $tags);
+    }
+}

+ 80 - 0
lib/Alcaeus/MongoDbAdapter/Helper/WriteConcern.php

@@ -0,0 +1,80 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+namespace Alcaeus\MongoDbAdapter\Helper;
+
+/**
+ * @internal
+ */
+trait WriteConcern
+{
+    /**
+     * @var \MongoDB\Driver\WriteConcern
+     */
+    protected $writeConcern;
+
+    /**
+     * @param $wstring
+     * @param int $wtimeout
+     * @return bool
+     */
+    abstract public function setWriteConcern($wstring, $wtimeout = 0);
+
+    /**
+     * @return array
+     */
+    public function getWriteConcern()
+    {
+        if ($this->writeConcern === null) {
+            $this->writeConcern = new \MongoDB\Driver\WriteConcern(1);
+        }
+
+        return [
+            'w' => $this->writeConcern->getW(),
+            'wtimeout' => $this->writeConcern->getWtimeout(),
+        ];
+
+    }
+
+    /**
+     * @param string|int $wstring
+     * @param int $wtimeout
+     * @return bool
+     */
+    protected function setWriteConcernFromParameters($wstring, $wtimeout = 0)
+    {
+        if (! is_string($wstring) && ! is_int($wstring)) {
+            trigger_error("w for WriteConcern must be a string or integer", E_WARNING);
+            return false;
+        }
+
+        // Ensure wtimeout is not < 0
+        $this->writeConcern = new \MongoDB\Driver\WriteConcern($wstring, max($wtimeout, 0));
+
+        return true;
+    }
+
+    /**
+     * @param array $writeConcernArray
+     * @return bool
+     */
+    protected function setWriteConcernFromArray($writeConcernArray)
+    {
+        $wstring = $writeConcernArray['w'];
+        $wtimeout = isset($writeConcernArray['wtimeout']) ? $writeConcernArray['wtimeout'] : 0;
+
+        return $this->setWriteConcernFromParameters($wstring, $wtimeout);
+    }
+}

+ 5 - 13
lib/Mongo/MongoCursor.php

@@ -327,6 +327,11 @@ class MongoCursor extends AbstractCursor implements Iterator
     {
         $this->errorIfOpened();
         static::$slaveOkay = $okay;
+
+        $readPreferenceArray = $this->getReadPreference();
+        $readPreferenceArray['type'] = $okay ? \MongoClient::RP_SECONDARY_PREFERRED : \MongoClient::RP_PRIMARY;
+
+        $this->setReadPreferenceFromArray($readPreferenceArray);
     }
 
     /**
@@ -400,19 +405,6 @@ class MongoCursor extends AbstractCursor implements Iterator
     }
 
     /**
-     * {@inheritdoc}
-     */
-    protected function convertReadPreference()
-    {
-        $readPreference = parent::convertReadPreference();
-        if ($readPreference === null && static::$slaveOkay) {
-            $readPreference = new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED);
-        }
-
-        return $readPreference;
-    }
-
-    /**
      * @return Cursor
      */
     protected function ensureCursor()