Passed
Push — master ( 47ed60...652a71 )
by CodexShaper
04:59
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
    protected $db;
16
    protected $collection;
17
    protected $databaseName;
18
    protected $collectionName;
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
    public function renameCollection($fromNs, $toNs)
26
    {
27
        return $this->command(array('renameCollection' => $fromNs, 'to' => $toNs));
28
    }
29
30
    public function renameFields($collectionName, $fields)
31
    {
32
        $rename = [];
33
        foreach ($fields as $oldName => $newName) {
34
            $rename[$oldName] = $newName;
35
        }
36
        $update = array(
37
            '$rename' => $rename,
38
        );
39
40
        return $this->selectCollection($collectionName)->updateMany(array(), $update, array('upsert' => true));
41
    }
42
43
    public function getDB()
44
    {
45
        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

45
        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...
46
    }
47
48
    public function getNamespace($databaseName, $collectionName)
49
    {
50
        return $databaseName . '.' . $collectionName;
51
    }
52
53
    public function getCollections()
54
    {
55
        return $this->getDB()->listCollections();
56
    }
57
58
    public function getCollectionNames()
59
    {
60
        $collections     = $this->getCollections();
61
        $collectionNames = [];
62
        foreach ($collections as $key => $collection) {
63
            $collectionNames[] = $collection->getName();
64
        }
65
66
        return $collectionNames;
67
    }
68
69
    public function hasCollection($collectionName)
70
    {
71
        return (in_array($collectionName, $this->getCollectionNames())) ? true : false;
72
    }
73
74
    public function createCollection($collectionName)
75
    {
76
        return $this->getDB()->createCollection($collectionName);
77
    }
78
79
    public function getCollection($collectionName)
80
    {
81
        return [
82
            'name'           => $collectionName,
83
            'oldName'        => $collectionName,
84
            'columns'        => $this->getColumns($collectionName),
85
            'indexes'        => Index::getIndexes($this->selectCollection($collectionName)),
86
            'foreignKeys'    => [],
87
            'primaryKeyName' => ['_id'],
88
            'options'        => [],
89
        ];
90
    }
91
92
    public function updateCollection($collection)
93
    {
94
95
        $newName        = $collection['name'];
96
        $oldName        = $collection['oldName'];
97
        $collectionName = $oldName;
98
        $connection     = config('database.default');
99
        $database       = config('database.connections.' . $connection . ".database");
100
        $fromNs         = $this->getNamespace($database, $oldName);
101
        $toNs           = $this->getNamespace($database, $newName);
102
103
        if ($newName != $oldName) {
104
            $this->renameCollection($fromNs, $toNs);
105
            $collectionName = $newName;
106
        }
107
108
        $this->setFields($collectionName, $this->getColumns($collectionName));
109
        Index::setIndexes($this->selectCollection($collectionName), $collection['indexes']);
110
111
        return true;
112
113
    }
114
115
    public function renameColumns($collectionName, $fields)
116
    {
117
        $collection = $this->selectCollection($collectionName);
118
        $renames    = [];
119
        foreach ($fields as $field) {
120
            if ($field->oldName != "") {
121
                if ($field->oldName != $field->name) {
122
                    $renames[$field->oldName] = $field->name;
123
                }
124
125
            }
126
        }
127
        $update = [];
128
        if (count($renames) > 0) {
129
            $update['$rename'] = $renames;
130
            $collection->updateMany(array(), $update, array('upsert' => true));
131
            $dbmCollection = DBM_Collection::where('name', $collectionName)->first();
132
            foreach ($renames as $oldName => $newName) {
133
                $collection_field = CollectionField::where([
134
                    'dbm_collection_id' => $dbmCollection->_id,
135
                    'old_name'          => $oldName,
136
                ])->first();
137
                $collection_field->old_name = $newName;
138
                $collection_field->update();
139
            }
140
        }
141
    }
142
143
    public function addColumns($collectionName)
144
    {
145
        $collection = $this->selectCollection($collectionName);
146
        $newFields  = $this->getColumnsName($collectionName);
147
        $update     = [];
148
149
        if ($collection->count() > 0) {
150
            foreach ($newFields as $newField) {
151
                $cursor   = $collection->find();
152
                $iterator = iterator_to_array($cursor);
153
154
                foreach ($iterator as $document) {
155
                    $columnNames = [];
156
                    $id          = "";
157
                    foreach ($document as $columnName => $columnValue) {
158
                        if (is_object($columnValue)) {
159
                            foreach ($columnValue as $key => $value) {
160
                                if ($columnName == '_id') {
161
                                    $id = $value;
162
                                }
163
                            }
164
                        }
165
                        $columnNames[] = $columnName;
166
                    }
167
168
                    if ($id != "" && !in_array($newField, $columnNames)) {
169
                        $update['$set'] = array($newField => "");
170
                        $collection->updateOne(
171
                            array("_id" => new \MongoDB\BSON\ObjectID($id)),
172
                            $update,
173
                            array('upsert' => true)
174
                        );
175
                    }
176
                }
177
            }
178
179
        }
180
    }
181
182
    public function removeColumns($collectionName)
183
    {
184
        $collection = $this->selectCollection($collectionName);
185
        $newFields  = $this->getColumnsName($collectionName);
186
        $columns    = $this->getCollectionColumns($collectionName);
187
        $update     = [];
188
        $unsets     = [];
189
190
        foreach ($columns as $column) {
191
            if (!in_array($column, $newFields)) {
192
                $unsets[$column] = "";
193
            }
194
        }
195
196
        if (count($unsets) > 0) {
197
            $update['$unset'] = $unsets;
198
            $collection->updateMany(array(), $update, array('upsert' => true));
199
        }
200
    }
201
202
    public function setFields($collectionName, $fields)
203
    {
204
        /*
205
         * Rename Columns
206
         */
207
        $this->renameColumns($collectionName, $fields);
208
209
        /*
210
         * Add Columns
211
         */
212
        $this->addColumns($collectionName);
213
        /*
214
         * Remove Columns
215
         */
216
        $this->removeColumns($collectionName);
217
        return true;
218
    }
219
220
    public function dropCollection($collectionName)
221
    {
222
        $this->getDB()->dropCollection($collectionName);
223
    }
224
225
    public function selectCollection($collectionName)
226
    {
227
        return $this->getDB()->selectCollection($collectionName);
228
    }
229
230
    public function getCollectionColumns($collectionName)
231
    {
232
        $cursor      = $this->selectCollection($collectionName)->find();
233
        $iterator    = iterator_to_array($cursor);
234
        $columnNames = [];
235
236
        foreach ($iterator as $document) {
237
            foreach ($document as $columnName => $columnValue) {
238
                $columnNames[] = $columnName;
239
            }
240
        }
241
242
        return array_values(array_unique($columnNames));
243
    }
244
245
    public function getColumns($collectionName)
246
    {
247
        $columns = [];
248
249
        if ($collection = DBM_Collection::where('name', $collectionName)->first()) {
250
251
            $fields = $collection->fields;
252
            foreach ($fields as $field) {
253
                $columns[] = (object) [
254
                    "name"          => $field->name,
255
                    "oldName"       => $field->old_name,
256
                    "type"          => [
257
                        "name" => $field->type,
258
                    ],
259
                    "autoincrement" => false,
260
                    "default"       => null,
261
                    "length"        => null,
262
                ];
263
            }
264
        } else {
265
            $fields = $this->getCollectionColumns($collectionName);
266
            foreach ($fields as $field) {
267
                $columns[] = (object) [
268
                    "name"          => $field,
269
                    "oldName"       => $field,
270
                    "type"          => [
271
                        "name" => "",
272
                    ],
273
                    "autoincrement" => false,
274
                    "default"       => null,
275
                    "length"        => null,
276
                ];
277
            }
278
        }
279
280
        return $columns;
281
    }
282
283
    public function getColumnsName($collectionName)
284
    {
285
        return DBM_Collection::where('name', $collectionName)->first()->fields->pluck('name')->toArray();
286
    }
287
288
}
289