Passed
Push — master ( 0ed784...b28e07 )
by CodexShaper
14:16
created

MongoDB::getColumns()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 24
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 36
rs 9.536
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');
0 ignored issues
show
Bug introduced by
The function config was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

98
        $connection     = /** @scrutinizer ignore-call */ config('database.default');
Loading history...
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 setFields($collectionName, $fields)
116
    {
117
        $collection = $this->selectCollection($collectionName);
118
        /*
119
         * Rename Columns
120
         */
121
        $renames = [];
122
        foreach ($fields as $field) {
123
            if ($field->oldName != "") {
124
                if ($field->oldName != $field->name) {
125
                    $renames[$field->oldName] = $field->name;
126
                }
127
128
            }
129
        }
130
        $update = [];
131
        if (count($renames) > 0) {
132
            $update['$rename'] = $renames;
133
            $collection->updateMany(array(), $update, array('upsert' => true));
134
            foreach ($renames as $oldName => $newName) {
135
                $collection_field           = CollectionField::where('old_name', $oldName)->first();
136
                $collection_field->old_name = $newName;
137
                $collection_field->update();
138
            }
139
        }
140
141
        $newFields = $this->getColumnsName($collectionName);
142
        $columns   = $this->getCollectionColumns($collectionName);
143
144
        /*
145
         * Add Columns
146
         */
147
148
        if ($collection->count() > 0) {
149
            $sets = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $sets is dead and can be removed.
Loading history...
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
         * Remove Columns
183
         */
184
185
        $update = [];
186
187
        $unsets = [];
188
        foreach ($columns as $column) {
189
            if (!in_array($column, $newFields)) {
190
                $unsets[$column] = "";
191
            }
192
        }
193
194
        if (count($unsets) > 0) {
195
            $update['$unset'] = $unsets;
196
            $collection->updateMany(array(), $update, array('upsert' => true));
197
        }
198
199
        return true;
200
    }
201
202
    public function dropCollection($collectionName)
203
    {
204
        $this->getDB()->dropCollection($collectionName);
205
    }
206
207
    public function selectCollection($collectionName)
208
    {
209
        return $this->getDB()->selectCollection($collectionName);
210
    }
211
212
    public function getCollectionColumns($collectionName)
213
    {
214
        $cursor      = $this->selectCollection($collectionName)->find();
215
        $iterator    = iterator_to_array($cursor);
216
        $columnNames = [];
217
218
        foreach ($iterator as $document) {
219
            foreach ($document as $columnName => $columnValue) {
220
                $columnNames[] = $columnName;
221
            }
222
        }
223
224
        return array_values(array_unique($columnNames));
225
    }
226
227
    public function getColumns($collectionName)
228
    {
229
        $columns = [];
230
231
        if ($collection = DBM_Collection::where('name', $collectionName)->first()) {
232
233
            $fields = $collection->fields;
234
            foreach ($fields as $field) {
235
                $columns[] = (object) [
236
                    "name"          => $field->name,
237
                    "oldName"       => $field->old_name,
238
                    "type"          => [
239
                        "name" => $field->type,
240
                    ],
241
                    "autoincrement" => false,
242
                    "default"       => null,
243
                    "length"        => null,
244
                ];
245
            }
246
        } else {
247
            $fields = $this->getCollectionColumns($collectionName);
248
            foreach ($fields as $field) {
249
                $columns[] = (object) [
250
                    "name"          => $field,
251
                    "oldName"       => $field,
252
                    "type"          => [
253
                        "name" => "",
254
                    ],
255
                    "autoincrement" => false,
256
                    "default"       => null,
257
                    "length"        => null,
258
                ];
259
            }
260
        }
261
262
        return $columns;
263
    }
264
265
    public function getColumnsName($collectionName)
266
    {
267
        return DBM_Collection::where('name', $collectionName)->first()->fields->pluck('name')->toArray();
268
    }
269
270
}
271