DbMigrations::write()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 1 Features 3
Metric Value
c 8
b 1
f 3
dl 0
loc 16
rs 9.4285
cc 2
eloc 8
nc 2
nop 0
1
<?php namespace Nwidart\DbExporter;
2
3
use Config;
4
use File;
5
use Nwidart\DbExporter\Exceptions\InvalidDatabaseException;
6
use Str;
7
8
class DbMigrations extends DbExporter
9
{
10
    protected $database;
11
12
    protected $selects = array(
13
        'column_name as Field',
14
        'column_type as Type',
15
        'is_nullable as Null',
16
        'column_key as Key',
17
        'column_default as Default',
18
        'extra as Extra',
19
        'data_type as Data_Type'
20
    );
21
22
    protected $schema;
23
24
    protected $customDb = false;
25
26
    public static $filePath;
27
28
    /**
29
     * Set the database name
30
     * @param String $database
31
     * @throw InvalidDatabaseException
32
     */
33
    function __construct($database)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
34
    {
35
        if (empty($database)) {
36
            throw new InvalidDatabaseException('No database set in app/config/database.php');
37
        }
38
39
        $this->database = $database;
40
    }
41
42
    /**
43
     * Write the prepared migration to a file
44
     */
45
    public function write()
46
    {
47
        // Check if convert method was called before
48
        // If not, call it on default DB
49
        if (!$this->customDb) {
50
            $this->convert();
51
        }
52
53
        $schema = $this->compile();
54
        $filename = date('Y_m_d_His') . "_create_" . $this->database . "_database.php";
55
        self::$filePath = config('db-exporter.export_path.migrations')."{$filename}";
56
57
        file_put_contents(self::$filePath, $schema);
58
59
        return self::$filePath;
60
    }
61
62
    /**
63
     * Convert the database to migrations
64
     * If none is given, use de DB from condig/database.php
65
     * @param null $database
66
     * @return $this
67
     */
68
    public function convert($database = null)
0 ignored issues
show
Complexity introduced by
This operation has 380018 execution paths which exceeds the configured maximum of 200.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

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

Loading history...
69
    {
70
        if (!is_null($database)) {
71
            $this->database = $database;
72
            $this->customDb = true;
73
        }
74
75
        $tables = $this->getTables();
76
77
        // Loop over the tables
78
        foreach ($tables as $key => $value) {
79
            // Do not export the ignored tables
80
            if (in_array($value['table_name'], self::$ignore)) {
81
                continue;
82
            }
83
84
            $down = "Schema::drop('{$value['table_name']}');";
85
            $up = "Schema::create('{$value['table_name']}', function(Blueprint $" . "table) {\n";
86
87
            $tableDescribes = $this->getTableDescribes($value['table_name']);
88
            // Loop over the tables fields
89
            foreach ($tableDescribes as $values) {
90
                $method = "";
91
                $para = strpos($values->Type, '(');
92
                $type = $para > -1 ? substr($values->Type, 0, $para) : $values->Type;
93
                $numbers = "";
94
                $nullable = $values->Null == "NO" ? "" : "->nullable()";
95
                $default = empty($values->Default) ? "" : "->default('".$values->Default."')";
96
                $unsigned = strpos($values->Type, "unsigned") === false ? '' : '->unsigned()';
97
98
                switch ($type) {
99
                    case 'int' :
100
                        $method = 'integer';
101
                        break;
102
                    case 'smallint' :
103
                        $method = 'smallInteger';
104
                        break;
105
                    case 'bigint' :
106
                        $method = 'bigInteger';
107
                        break;
108
                    case 'char' :
109
                    case 'varchar' :
110
                        $para = strpos($values->Type, '(');
111
                        $numbers = ", " . substr($values->Type, $para + 1, -1);
112
                        $method = 'string';
113
                        break;
114
                    case 'float' :
115
                        $method = 'float';
116
                        break;
117
                    case 'double' :
118
                        $para = strpos($values->Type, '('); # 6
119
                        $numbers = ", " . substr($values->Type, $para + 1, -1);
120
                        $method = 'double';
121
                        break;
122
                    case 'decimal' :
123
                        $para = strpos($values->Type, '(');
124
                        $numbers = ", " . substr($values->Type, $para + 1, -1);
125
                        $method = 'decimal';
126
                        break;
127
                    case 'tinyint' :
128
                        $method = 'boolean';
129
                        break;
130
                    case 'date' :
131
                        $method = 'date';
132
                        break;
133
                    case 'timestamp' :
134
                        $method = 'timestamp';
135
                        break;
136
                    case 'datetime' :
137
                        $method = 'dateTime';
138
                        break;
139
                    case 'time' :
140
                        $method = 'time';
141
                        break;
142
                    case 'longtext' :
143
                        $method = 'longText';
144
                        break;
145
                    case 'mediumtext' :
146
                        $method = 'mediumText';
147
                        break;
148
                    case 'text' :
149
                        $method = 'text';
150
                        break;
151
                    case 'longblob':
152
                    case 'blob' :
153
                        $method = 'binary';
154
                        break;
155
                    case 'enum' :
156
                        $method = 'enum';
157
                        $para = strpos($values->Type, '('); # 4
158
                        $options = substr($values->Type, $para + 1, -1);
159
                        $numbers = ', array(' . $options . ')';
160
                        break;
161
                }
162
163
                if ($values->Key == 'PRI') {
164
                    $method = 'increments';
165
                }
166
167
                $up .= "                $" . "table->{$method}('{$values->Field}'{$numbers}){$nullable}{$default}{$unsigned};\n";
168
            }
169
170
            $tableIndexes = $this->getTableIndexes($value['table_name']);
171
            if (!is_null($tableIndexes) && count($tableIndexes)){
172
            	foreach ($tableIndexes as $index) {
173
                	$up .= '                $' . "table->index('" . $index['Key_name'] . "');\n";
174
            	}
175
        	}
176
177
            $up .= "            });\n\n";
178
179
            $this->schema[$value['table_name']] = array(
180
                'up'   => $up,
181
                'down' => $down
182
            );
183
        }
184
185
        return $this;
186
    }
187
188
    /**
189
     * Compile the migration into the base migration file
190
     * TODO use a template with seacrh&replace
191
     * @return string
192
     */
193
    protected function compile()
194
    {
195
        $upSchema = "";
196
        $downSchema = "";
197
198
        // prevent of failure when no table
199
        if (!is_null($this->schema) && count($this->schema)) {
200
	        foreach ($this->schema as $name => $values) {
201
	            // check again for ignored tables
202
	            if (in_array($name, self::$ignore)) {
203
	                continue;
204
	            }
205
	            $upSchema .= "
206
	    /**
207
	     * Table: {$name}
208
	     */
209
	    {$values['up']}";
210
211
	            $downSchema .= "
212
	            {$values['down']}";
213
	        }
214
        }
215
216
        // Grab the template
217
        $template = File::get(__DIR__ . '/templates/migration.txt');
218
219
        // Replace the classname
220
        $template = str_replace('{{name}}', "Create" . Str::title($this->database) . "Database", $template);
221
222
        // Replace the up and down values
223
        $template = str_replace('{{up}}', $upSchema, $template);
224
        $template = str_replace('{{down}}', $downSchema, $template);
225
226
        return $template;
227
    }
228
229
}
230