Completed
Push — master ( 22ba9b...c139c0 )
by Andreas
11s
created

MongoCommandCursor   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 140
rs 10
c 0
b 0
f 0
wmc 29
lcom 1
cbo 3

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A createFromDocument() 0 4 1
C ensureCursor() 0 27 7
A getCursorInfo() 0 12 1
A getIterationInfo() 0 15 2
A __sleep() 0 4 1
C supportsReadPreference() 0 30 16
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 */
15
16
if (class_exists('MongoCommandCursor', false)) {
17
    return;
18
}
19
20
use Alcaeus\MongoDbAdapter\AbstractCursor;
21
use Alcaeus\MongoDbAdapter\TypeConverter;
22
23
class MongoCommandCursor extends AbstractCursor implements MongoCursorInterface
24
{
25
    /**
26
     * @var array
27
     */
28
    private $command;
29
30
    /**
31
     * MongoCommandCursor constructor.
32
     * @param MongoClient $connection
33
     * @param string $ns
34
     * @param array $command
35
     */
36
    public function __construct(MongoClient $connection, $ns, array $command = [])
37
    {
38
        parent::__construct($connection, $ns);
39
40
        $this->command = $command;
41
    }
42
43
    /**
44
     * @param MongoClient $connection
45
     * @param string $hash
46
     * @param array $document
47
     * @return MongoCommandCursor
48
     */
49
    public static function createFromDocument(MongoClient $connection, $hash, array $document)
0 ignored issues
show
Unused Code introduced by
The parameter $connection is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $hash is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $document is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
50
    {
51
        throw new \Exception('Not implemented');
52
    }
53
54
    /**
55
     * @return \MongoDB\Driver\Cursor
56
     */
57
    protected function ensureCursor()
58
    {
59
        if ($this->cursor === null) {
60
            $convertedCommand = TypeConverter::fromLegacy($this->command);
61
            if (isset($convertedCommand->cursor)) {
62
                if ($convertedCommand->cursor === true || $convertedCommand->cursor === []) {
63
                    $convertedCommand->cursor = new \stdClass();
64
                }
65
            }
66
67
            $originalReadPreference = null;
68
            if (!$this->supportsReadPreference()) {
69
                $originalReadPreference = $this->readPreference;
70
                $this->setReadPreference(\MongoClient::RP_PRIMARY);
71
            }
72
73
            try {
74
                $this->cursor = $this->db->command($convertedCommand, $this->getOptions());
75
            } finally {
76
                if ($originalReadPreference) {
77
                    $this->readPreference = $originalReadPreference;
78
                }
79
            }
80
        }
81
82
        return $this->cursor;
83
    }
84
85
    /**
86
     * @return array
87
     */
88
    protected function getCursorInfo()
89
    {
90
        return [
91
            'ns' => $this->ns,
92
            'limit' => 0,
93
            'batchSize' => $this->batchSize,
94
            'skip' => 0,
95
            'flags' => 0,
96
            'query' => $this->command,
97
            'fields' => null,
98
        ];
99
    }
100
101
    /**
102
     * @return array
103
     */
104
    protected function getIterationInfo()
105
    {
106
        $iterationInfo = parent::getIterationInfo();
107
108
        if ($iterationInfo['started_iterating']) {
109
            $iterationInfo += [
110
                'firstBatchAt' => $iterationInfo['at'],
111
                'firstBatchNumReturned' => $iterationInfo['numReturned'],
112
            ];
113
            $iterationInfo['at'] = 0;
114
            $iterationInfo['numReturned'] = 0;
115
        }
116
117
        return $iterationInfo;
118
    }
119
120
    /**
121
     * @return array
122
     */
123
    public function __sleep()
124
    {
125
        return ['command'] + parent::__sleep();
126
    }
127
128
    /**
129
     * @see https://github.com/mongodb/mongo-php-driver-legacy/blob/1.6.14/db.c#L51
130
     * @return bool
131
     */
132
    private function supportsReadPreference()
133
    {
134
        if ($this->command === []) {
135
            return false;
136
        }
137
138
        $firstKey = array_keys($this->command)[0];
139
        switch ($firstKey) {
140
            case 'count':
141
            case 'group':
142
            case 'dbStats':
143
            case 'geoNear':
144
            case 'geoWalk':
145
            case 'distinct':
146
            case 'aggregate':
147
            case 'collStats':
148
            case 'geoSearch':
149
            case 'parallelCollectionScan':
150
                return true;
151
152
            case 'mapreduce':
153
            case 'mapReduce':
154
                return (isset($this->command['out']) &&
155
                    is_array($this->command['out']) &&
156
                    array_key_exists('inline', $this->command['out']));
157
158
            default:
159
                return false;
160
        }
161
    }
162
}
163