Import::generateSchemaCode()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
c 2
b 0
f 0
nc 4
nop 3
dl 0
loc 7
rs 10
1
<?php
2
3
namespace yentu\commands;
4
5
use clearice\io\Io;
6
use yentu\CodeWriter;
7
use yentu\exceptions\CommandException;
8
use yentu\exceptions\NonReversibleCommandException;
9
use yentu\factories\DatabaseManipulatorFactory;
10
use yentu\Migrations;
11
use ntentan\utils\Filesystem;
12
13
class Import extends Command
14
{
15
    private $db;
16
    private $code;
17
    private $hasSchema = false;
18
    private $foreignKeys = array();
19
    private $newVersion;
20
    private $manipulatorFactory;
21
    private $migrations;
22
    private $io;
23
24
    public function __construct(Migrations $migrations, DatabaseManipulatorFactory $manipulatorFactory, Io $io, CodeWriter $codeWriter)
25
    {
26
        $this->manipulatorFactory = $manipulatorFactory;
27
        $this->migrations = $migrations;
28
        $this->io = $io;
29
        $this->code = $codeWriter;
30
    }
31
32
    public function run()
33
    {
34
        $this->db = $this->manipulatorFactory->createManipulator();
35
        $files = scandir($this->migrations->getPath("migrations"));
36
        if (count($files) > 2) {
37
            throw new NonReversibleCommandException("Cannot run imports. Your migrations directory is not empty");
38
        }
39
        $description = $this->db->getDescription();
40
41
        $this->code->add('begin()');
42
        if (isset($description['schemata'])) {
43
            $this->importSchemata($description['schemata']);
44
        }
45
        if (isset($description['tables'])) {
46
            $this->importTables($description['tables']);
47
        }
48
        if (isset($description['views'])) {
49
            $this->importViews($description['views']);
50
        }
51
52
        $this->importForeignKeys();
53
        $this->code->add('->end();');
54
55
        $this->newVersion = date('YmdHis', time());
56
        $path = $this->migrations->getPath("migrations/{$this->newVersion}_import.php");
57
        Filesystem::file($path)->putContents($this->code);
58
        $this->io->output("Created `$path`\n");
59
        if (!$this->db->getAssertor()->doesTableExist('yentu_history')) {
60
            $this->db->createHistory();
61
        }
62
        $this->db->setVersion($this->newVersion);
63
        $this->db->disconnect();
64
65
        return $description;
66
    }
67
68
    public function getNewVersion()
69
    {
70
        return $this->newVersion;
71
    }
72
73
    private function generateSchemaCode($description, $ref = false, $prefix = '')
74
    {
75
        $refprefix = $ref === true ? 'ref' : '->';
76
        if ($description["{$prefix}schema"] == false) {
77
            return "{$refprefix}table('{$description["{$prefix}table"]}')";
78
        } else {
79
            return "{$refprefix}schema('{$description["{$prefix}schema"]}')->table('{$description["{$prefix}table"]}')";
80
        }
81
    }
82
83
    protected function importForeignKeys()
84
    {
85
        foreach ($this->foreignKeys as $name => $foreignKey) {
86
            $this->code->add($this->generateSchemaCode($foreignKey));
87
            $this->code->addIndent();
88
            $this->code->add("->foreignKey('" . implode("','", $foreignKey['columns']) . "')");
89
            $reference = $this->generateSchemaCode($foreignKey, true, 'foreign_');
90
            $this->code->add("->references({$reference})");
91
            $this->code->add("->columns('" . implode("','", $foreignKey['foreign_columns']) . "')");
92
93
            if ($foreignKey['on_delete'] != '') {
94
                $this->code->add("->onDelete('{$foreignKey['on_delete']}')");
95
            }
96
97
            if ($foreignKey['on_update'] != '') {
98
                $this->code->add("->onUpdate('{$foreignKey['on_update']}')");
99
            }
100
101
            $this->code->add("->name('$name')");
102
            $this->code->decreaseIndent();
103
            $this->code->ln();
104
        }
105
    }
106
107
    protected function importColumns($columns)
108
    {
109
        foreach ($columns as $column) {
110
            $this->code->addNoLn("->column('{$column['name']}')");
111
            $this->code->addNoIndent("->type('{$column['type']}')");
112
            $this->code->addNoIndent("->nulls(" . ($column['nulls'] === true ? 'true' : 'false') . ")");
113
114
            if ($column['length'] != '') {
115
                $this->code->addNoIndent("->length({$column['length']})");
116
            }
117
            if ($column['default'] != '') {
118
                $this->code->addNoIndent("->defaultValue(\"{$column['default']}\")");
119
            }
120
121
            $this->code->ln();
122
        }
123
    }
124
125
    protected function importSchemata($schemata)
126
    {
127
        $this->code->add('// Schemata');
128
129
        if (count($schemata) > 0) {
130
            $this->hasSchema = true;
131
        }
132
133
        foreach ($schemata as $schema) {
134
            $this->code->add("->schema('{$schema['name']}')");
135
            $this->code->addIndent();
136
            $this->importTables($schema['tables']);
137
            $this->importViews($schema['views']);
138
            $this->code->decreaseIndent();
139
        }
140
141
        $this->hasSchema = false;
142
    }
143
144
    protected function importViews($views)
145
    {
146
        foreach ($views as $view) {
147
            $definition = sprintf('->definition("%s")', str_replace('"', '\"', $view['definition']));
148
            $this->code->add("->view('{$view['name']}')$definition");
149
            $this->code->ln();
150
        }
151
    }
152
153
    protected function importTables($tables)
154
    {
155
        foreach ($tables as $table) {
156
            if ($table['name'] == 'yentu_history')
157
                continue;
158
159
            $this->code->add("->table('{$table['name']}')");
160
            $this->code->addIndent();
161
162
            $this->importColumns($table['columns']);
163
            $this->importConstraints('primaryKey', $table['primary_key']);
164
165
            if ($table['auto_increment']) {
166
                $this->code->add("->autoIncrement()");
167
            }
168
            $this->importConstraints('unique', $table['unique_keys']);
169
            $this->importConstraints('index', $table['indices']);
170
171
            $this->code->decreaseIndent();
172
            $this->code->ln();
173
174
            if (count($table['foreign_keys']) > 0) {
175
                $this->foreignKeys = array_merge($this->foreignKeys, $table['foreign_keys']);
176
            }
177
        }
178
    }
179
180
    protected function importConstraints($type, $constraints)
181
    {
182
        foreach ($constraints as $name => $constraint) {
183
            $constraint = implode("','", $constraint['columns']);
184
            $this->code->add("->$type('$constraint')->name('$name')");
185
        }
186
    }
187
}
188
189