Completed
Push — master ( ffe8b5...553b6e )
by CodexShaper
76:19 queued 70:43
created

MongoDB::getCollectionNames()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 9
ccs 0
cts 8
cp 0
crap 6
rs 10
1
<?php
2
3
namespace CodexShaper\DBM\Database\Drivers;
4
5
use CodexShaper\DBM\Database\Drivers\MongoDB\Index;
6
use CodexShaper\DBM\Models\CollectionField;
7
use CodexShaper\DBM\Models\DBM_Collection;
8
use CodexShaper\DBM\Traits\MongoConnection;
9
use Illuminate\Support\Facades\DB;
10
11
class MongoDB
12
{
13
    use MongoConnection;
14
15
    /**
16
     * Run MongoDB command.
17
     *
18
     * @return  \MongoDB\Driver\Cursor
19
     */
20
    public function command(array $command)
21
    {
22
        return static::getMongoClient()->{$this->admin}->command($command);
0 ignored issues
show
Bug Best Practice introduced by
The method CodexShaper\DBM\Database...ngoDB::getMongoClient() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

22
        return static::/** @scrutinizer ignore-call */ getMongoClient()->{$this->admin}->command($command);
Loading history...
23
    }
24
25
    /**
26
     * Rename collection.
27
     *
28
     * @param   string  $fromNs
29
     * @param   string  $toNs
30
     *
31
     * @return  \MongoDB\Driver\Cursor
32
     */
33
    public function renameCollection($fromNs, $toNs)
34
    {
35
        return $this->command(['renameCollection' => $fromNs, 'to' => $toNs]);
36
    }
37
38
    /**
39
     * Rename fields.
40
     *
41
     * @param   string  $collectionName
42
     * @param   array   $fields
43
     *
44
     * @return  void
45
     */
46
    public function renameFields($collectionName, $fields)
47
    {
48
        $rename = [];
49
        foreach ($fields as $oldName => $newName) {
50
            $rename[$oldName] = $newName;
51
        }
52
        $update = [
53
            '$rename' => $rename,
54
        ];
55
56
        $this->selectCollection($collectionName)->updateMany([], $update, ['upsert' => true]);
57
    }
58
59
    /**
60
     * Get the MongoDB database object.
61
     *
62
     * @return  \MongoDB\Database
0 ignored issues
show
Bug introduced by
The type MongoDB\Database was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
63
     */
64
    public function getDB()
65
    {
66
        return DB::connection()->getMongoDB();
0 ignored issues
show
Bug introduced by
The method getMongoDB() does not exist on Illuminate\Database\ConnectionInterface. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        return DB::connection()->/** @scrutinizer ignore-call */ getMongoDB();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
67
    }
68
69
    /**
70
     * Get the MongoDB collection namespace.
71
     *
72
     * @param   string  $databaseName
73
     * @param   string  $collectionName
74
     * @return string
75
     */
76
    public function getNamespace($databaseName, $collectionName)
77
    {
78
        return $databaseName . '.' . $collectionName;
79
    }
80
81
    /**
82
     * Get the all collections.
83
     *
84
     * @return  \MongoDB\Model\CollectionInfoIterator
0 ignored issues
show
Bug introduced by
The type MongoDB\Model\CollectionInfoIterator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
85
     */
86
    public function getCollections()
87
    {
88
        return $this->getDB()->listCollections();
89
    }
90
91
    /**
92
     * Get the all collections name.
93
     *
94
     * @return  array
95
     */
96
    public function getCollectionNames()
97
    {
98
        $collections = $this->getCollections();
99
        $collectionNames = [];
100
        foreach ($collections as $key => $collection) {
101
            $collectionNames[] = $collection->getName();
102
        }
103
104
        return $collectionNames;
105
    }
106
107
    /**
108
     * Check MongoDB collection.
109
     *
110
     * @param   string $collectionName
111
     *
112
     * @return  bool
113
     */
114
    public function hasCollection($collectionName)
115
    {
116
        return (in_array($collectionName, $this->getCollectionNames())) ? true : false;
117
    }
118
119
    /**
120
     * Create MongoDB colelction.
121
     *
122
     * @param   string $collectionName
123
     *
124
     * @return  array|object Command result document
125
     */
126
    public function createCollection($collectionName)
127
    {
128
        return $this->getDB()->createCollection($collectionName);
129
    }
130
131
    /**
132
     * Get MongoDB colelction.
133
     *
134
     * @param   string $collectionName
135
     *
136
     * @return  array
137
     */
138
    public function getCollection($collectionName)
139
    {
140
        return [
141
            'name' => $collectionName,
142
            'oldName' => $collectionName,
143
            'columns' => $this->getColumns($collectionName),
144
            'indexes' => Index::getIndexes($this->selectCollection($collectionName)),
145
            'foreignKeys' => [],
146
            'primaryKeyName' => ['_id'],
147
            'options' => [],
148
        ];
149
    }
150
151
    /**
152
     * Update MongoDB colelction.
153
     *
154
     * @param   array $collection
155
     *
156
     * @return  bool
157
     */
158
    public function updateCollection($collection)
159
    {
160
161
        $newName = $collection['name'];
162
        $oldName = $collection['oldName'];
163
        $collectionName = $oldName;
164
        $connection = config('database.default');
165
        $database = config('database.connections.' . $connection . '.database');
166
        $fromNs = $this->getNamespace($database, $oldName);
167
        $toNs = $this->getNamespace($database, $newName);
168
169
        if ($newName != $oldName) {
170
            $this->renameCollection($fromNs, $toNs);
171
            $collectionName = $newName;
172
        }
173
174
        $this->setFields($collectionName, $this->getColumns($collectionName));
175
        Index::setIndexes($this->selectCollection($collectionName), $collection['indexes']);
176
177
        return true;
178
179
    }
180
181
    /**
182
     * Rename MongoDB colelction columns.
183
     *
184
     * @param   string $collectionName
185
     * @param   array $fields
186
     *
187
     * @return  void
188
     */
189
    public function renameColumns($collectionName, $fields)
190
    {
191
        $collection = $this->selectCollection($collectionName);
192
        $renames = [];
193
        foreach ($fields as $field) {
194
            if ($field->oldName != '') {
195
                if ($field->oldName != $field->name) {
196
                    $renames[$field->oldName] = $field->name;
197
                }
198
199
            }
200
        }
201
        $update = [];
202
        if ($field->oldName != '') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $field seems to be defined by a foreach iteration on line 193. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
203
            $update['$rename'] = $renames;
204
            $collection->updateMany([], $update, ['upsert' => true]);
205
            $dbmCollection = DBM_Collection::where('name', $collectionName)->first();
206
            foreach ($renames as $oldName => $newName) {
207
                $collection_field = CollectionField::where([
208
                    'dbm_collection_id' => $dbmCollection->_id,
209
                    'old_name' => $oldName,
210
                ])->first();
211
                $collection_field->old_name = $newName;
212
                $collection_field->update();
213
            }
214
        }
215
    }
216
217
    /**
218
     * Add MongoDB colelction columns.
219
     *
220
     * @param   string $collectionName
221
     *
222
     * @return  void
223
     */
224
    public function addColumns($collectionName)
225
    {
226
        $collection = $this->selectCollection($collectionName);
227
        $newFields = $this->getColumnsName($collectionName);
228
        $update = [];
229
230
        if ($collection->count() > 0) {
231
            foreach ($newFields as $newField) {
232
                $cursor = $collection->find();
233
                $iterator = iterator_to_array($cursor);
234
235
                foreach ($iterator as $document) {
236
                    $columnNames = [];
237
                    $id = '';
238
                    foreach ($document as $columnName => $columnValue) {
239
                        if (is_object($columnValue)) {
240
                            foreach ($columnValue as $key => $value) {
241
                                if ($columnName == '_id') {
242
                                    $id = $value;
243
                                }
244
                            }
245
                        }
246
                        $columnNames[] = $columnName;
247
                    }
248
249
                    if ($id != '' && !in_array($newField, $columnNames)) {
250
                        $update['$set'] = [$newField => ''];
251
                        $collection->updateOne(
252
                            ['_id' => new \MongoDB\BSON\ObjectID($id)],
253
                            $update,
254
                            ['upsert' => true]
255
                        );
256
                    }
257
                }
258
            }
259
260
        }
261
    }
262
263
    /**
264
     * Remove MongoDB colelction columns.
265
     *
266
     * @param   string $collectionName
267
     *
268
     * @return  void
269
     */
270
    public function removeColumns($collectionName)
271
    {
272
        $collection = $this->selectCollection($collectionName);
273
        $newFields = $this->getColumnsName($collectionName);
274
        $columns = $this->getCollectionColumns($collectionName);
275
        $update = [];
276
        $unsets = [];
277
278
        foreach ($columns as $column) {
279
            if (!in_array($column, $newFields)) {
280
                $unsets[$column] = '';
281
            }
282
        }
283
284
        if (count($unsets) > 0) {
285
            $update['$unset'] = $unsets;
286
            $collection->updateMany([], $update, ['upsert' => true]);
287
        }
288
    }
289
290
    /**
291
     * Set MongoDB colelction fields.
292
     *
293
     * @param   string $collectionName
294
     * @param   array $fields
295
     *
296
     * @return  void
297
     */
298
    public function setFields($collectionName, $fields)
299
    {
300
        //Rename Columns
301
        $this->renameColumns($collectionName, $fields);
302
        //Add Columns
303
        $this->addColumns($collectionName);
304
        //Remove Columns
305
        $this->removeColumns($collectionName);
306
    }
307
308
    /**
309
     * Drop MongoDB colelction.
310
     *
311
     * @param   string $collectionName
312
     *
313
     * @return  void
314
     */
315
    public function dropCollection($collectionName)
316
    {
317
        $this->getDB()->dropCollection($collectionName);
318
    }
319
320
    /**
321
     * Select MongoDB colelction.
322
     *
323
     * @param   string $collectionName
324
     *
325
     * @return  \MongoDB\Collection
0 ignored issues
show
Bug introduced by
The type MongoDB\Collection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
326
     */
327
    public function selectCollection($collectionName)
328
    {
329
        return $this->getDB()->selectCollection($collectionName);
330
    }
331
332
    /**
333
     * Get MongoDB colelction columns.
334
     *
335
     * @param   string $collectionName
336
     *
337
     * @return  array
338
     */
339
    public function getCollectionColumns($collectionName)
340
    {
341
        $cursor = $this->selectCollection($collectionName)->find();
342
        $iterator = iterator_to_array($cursor);
343
        $columnNames = [];
344
345
        foreach ($iterator as $document) {
346
            foreach ($document as $columnName => $columnValue) {
347
                $columnNames[] = $columnName;
348
            }
349
        }
350
351
        return array_values(array_unique($columnNames));
352
    }
353
354
    /**
355
     * Get MongoDB columns.
356
     *
357
     * @param   string $collectionName
358
     *
359
     * @return  array
360
     */
361
    public function getColumns($collectionName)
362
    {
363
        $columns = [];
364
365
        if ($collection = DBM_Collection::where('name', $collectionName)->first()) {
366
367
            $fields = $collection->fields;
368
            foreach ($fields as $field) {
369
                $columns[] = (object) [
370
                    'name' => $field->name,
371
                    'oldName' => $field->old_name,
372
                    'type' => [
373
                        'name' => $field->type,
374
                    ],
375
                    'autoincrement' => false,
376
                    'default' => null,
377
                    'length' => null,
378
                ];
379
            }
380
        } else {
381
            $fields = $this->getCollectionColumns($collectionName);
382
            foreach ($fields as $field) {
383
                $columns[] = (object) [
384
                    'name' => $field,
385
                    'oldName' => $field,
386
                    'type' => [
387
                        'name' => '',
388
                    ],
389
                    'autoincrement' => false,
390
                    'default' => null,
391
                    'length' => null,
392
                ];
393
            }
394
        }
395
396
        return $columns;
397
    }
398
399
    /**
400
     * Get colelction ColumnsName.
401
     *
402
     * @param   string $collectionName
403
     *
404
     * @return  array
405
     */
406
    public function getColumnsName($collectionName)
407
    {
408
        return DBM_Collection::where('name', $collectionName)->first()->fields->pluck('name')->toArray();
409
    }
410
411
}
412