Completed
Branch 1707_add_explain_command (cbe7fb)
by Alessandro
02:54
created

Collection::findOneAndDelete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 8
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 8
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
crap 1
1
<?php declare(strict_types=1);
2
3
namespace Facile\MongoDbBundle\Capsule;
4
5
use Facile\MongoDbBundle\Event\QueryEvent;
6
use Facile\MongoDbBundle\Models\Query;
7
use MongoDB\Collection as MongoCollection;
8
use MongoDB\Driver\Manager;
9
use MongoDB\Driver\ReadPreference;
10
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
11
12
/**
13
 * Class Collection.
14
 * @internal
15
 */
16
final class Collection extends MongoCollection
17
{
18
    /** @var EventDispatcherInterface */
19
    private $eventDispatcher;
20
    /** @var string */
21
    private $clientName;
22
    /** @var string */
23
    private $databaseName;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
24
25
    /**
26
     * Collection constructor.
27
     *
28
     * @param Manager                  $manager
29
     * @param string                   $clientName
30
     * @param string                   $databaseName
31
     * @param string                   $collectionName
32
     * @param array                    $options
33
     * @param EventDispatcherInterface $eventDispatcher
34
     *
35
     * @internal param DataCollectorLoggerInterface $logger
36
     */
37 15 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38
        Manager $manager,
39
        string $clientName,
40
        string $databaseName,
41
        string $collectionName,
42
        array $options = [],
43
        EventDispatcherInterface $eventDispatcher
44
    ) {
45 15
        parent::__construct($manager, $databaseName, $collectionName, $options);
46 15
        $this->eventDispatcher = $eventDispatcher;
47 15
        $this->clientName = $clientName;
48 15
        $this->databaseName = $databaseName;
49 15
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54 1 View Code Duplication
    public function aggregate(array $pipeline, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
    {
56 1
        $query = $this->prepareQuery(__FUNCTION__, null, $pipeline, $options);
57 1
        $result = parent::aggregate($query->getData(), $query->getOptions());
58 1
        $this->notifyQueryExecution($query);
59
60 1
        return $result;
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 1 View Code Duplication
    public function count($filter = [], array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
67
    {
68 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options);
69 1
        $result = parent::count($query->getFilters(), $query->getOptions());
70 1
        $this->notifyQueryExecution($query);
71
72 1
        return $result;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 1 View Code Duplication
    public function find($filter = [], array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
79
    {
80 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options);
81 1
        $result = parent::find($query->getFilters(), $query->getOptions());
82 1
        $this->notifyQueryExecution($query);
83
84 1
        return $result;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 1 View Code Duplication
    public function findOne($filter = [], array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
    {
92 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options);
93 1
        $result = parent::findOne($query->getFilters(), $query->getOptions());
94 1
        $this->notifyQueryExecution($query);
95
96 1
        return $result;
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102 1 View Code Duplication
    public function findOneAndUpdate($filter, $update, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
    {
104 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, $update, $options);
105 1
        $result = parent::findOneAndUpdate($query->getFilters(), $query->getData(), $query->getOptions());
106 1
        $this->notifyQueryExecution($query);
107
108 1
        return $result;
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 1 View Code Duplication
    public function findOneAndDelete($filter, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
115
    {
116 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options);
117 1
        $result = parent::findOneAndDelete($query->getFilters(), $query->getOptions());
118 1
        $this->notifyQueryExecution($query);
119
120 1
        return $result;
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 2 View Code Duplication
    public function deleteMany($filter, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
    {
128 2
        $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options);
129 2
        $result = parent::deleteMany($query->getFilters(), $query->getOptions());
130 2
        $this->notifyQueryExecution($query);
131
132 2
        return $result;
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138 1 View Code Duplication
    public function deleteOne($filter, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
    {
140 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options);
141 1
        $result = parent::deleteOne($query->getFilters(), $query->getOptions());
142 1
        $this->notifyQueryExecution($query);
143
144 1
        return $result;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150 1 View Code Duplication
    public function replaceOne($filter, $replacement, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
    {
152 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, $replacement, $options);
153 1
        $result = parent::replaceOne($query->getFilters(), $query->getData(), $query->getOptions());
154 1
        $this->notifyQueryExecution($query);
155
156 1
        return $result;
157
    }
158
159
    /**
160
     * {@inheritdoc}
161
     */
162 2 View Code Duplication
    public function insertOne($document, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
    {
164 2
        $query = $this->prepareQuery(__FUNCTION__, [], $document, $options);
165 2
        $result = parent::insertOne($query->getData(), $query->getOptions());
166 2
        $this->notifyQueryExecution($query);
167
168 2
        return $result;
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174 1 View Code Duplication
    public function updateOne($filter, $update, array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
175
    {
176 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, $update, $options);
177 1
        $result = parent::updateOne($query->getFilters(), $query->getData(), $query->getOptions());
178 1
        $this->notifyQueryExecution($query);
179
180 1
        return $result;
181
    }
182
183
    /**
184
     * {@inheritdoc}
185
     */
186 1 View Code Duplication
    public function distinct($fieldName, $filter = [], array $options = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
187
    {
188 1
        $query = $this->prepareQuery(__FUNCTION__, $filter, ['fieldName' => $fieldName], $options);
189 1
        $result = parent::distinct($fieldName, $query->getFilters(), $query->getOptions());
190 1
        $this->notifyQueryExecution($query);
191
192 1
        return $result;
193
    }
194
195
    /**
196
     * @param string        $method
197
     * @param array|object  $filters
198
     * @param array|object  $data
199
     * @param array         $options
200
     *
201
     * @return Query
202
     */
203 12
    private function prepareQuery(string $method, $filters = null, $data = null, array $options): Query
204
    {
205 12
        $query = new Query();
206 12
        $query->setFilters($filters);
0 ignored issues
show
Bug introduced by
It seems like $filters defined by parameter $filters on line 203 can also be of type null; however, Facile\MongoDbBundle\Models\Query::setFilters() does only seem to accept array|object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
207 12
        $query->setData($data);
0 ignored issues
show
Bug introduced by
It seems like $data defined by parameter $data on line 203 can also be of type null; however, Facile\MongoDbBundle\Models\Query::setData() does only seem to accept array|object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
208 12
        $query->setOptions($options);
209 12
        $query->setMethod($method);
210 12
        $query->setClient($this->getClientName());
211 12
        $query->setDatabase($this->getDatabaseName());
212 12
        $query->setCollection($this->getCollectionName());
213 12
        $query->setReadPreference(
214 12
            $this->translateReadPreference($options['readPreference'] ?? $this->__debugInfo()['readPreference'])
215
        );
216
217 12
        $this->eventDispatcher->dispatch(QueryEvent::QUERY_PREPARED, new QueryEvent($query));
218
219 12
        return $query;
220
    }
221
222
    /**
223
     * @param ReadPreference $readPreference
224
     *
225
     * @return string
226
     */
227 12
    private function translateReadPreference(ReadPreference $readPreference): string
228
    {
229 12
        switch($readPreference->getMode()){
230 12
            case ReadPreference::RP_PRIMARY:
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
231
                return 'primary';
232 12
            case ReadPreference::RP_PRIMARY_PREFERRED:
233 12
                return 'primaryPreferred';
234
            case ReadPreference::RP_SECONDARY:
235
                return 'secondary';
236
            case ReadPreference::RP_SECONDARY_PREFERRED:
237
                return 'secondaryPreferred';
238
            case ReadPreference::RP_NEAREST:
239
                return 'nearest';
240
            default:
241
                return 'undefined';
242
        }
243
    }
244
245
    /**
246
     * @param Query $queryLog
247
     *
248
     * @return Query
249
     */
250 12
    private function notifyQueryExecution(Query $queryLog)
251
    {
252 12
        $queryLog->setExecutionTime(microtime(true) - $queryLog->getStart());
253
254 12
        $this->eventDispatcher->dispatch(QueryEvent::QUERY_EXECUTED, new QueryEvent($queryLog));
255 12
    }
256
257
    /**
258
     * @return string
259
     */
260 12
    public function getClientName(): string
261
    {
262 12
        return $this->clientName;
263
    }
264
265
    /**
266
     * @return string
267
     */
268 12
    public function getDatabaseName(): string
269
    {
270 12
        return $this->databaseName;
271
    }
272
}
273
274