Completed
Push — dev ( 812e58...1f57b5 )
by James Ekow Abaka
21:22
created

Import::reverseActions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
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 11
    private $io;
23
24 11
    public function __construct(Migrations $migrations, DatabaseManipulatorFactory $manipulatorFactory, Io $io, CodeWriter $codeWriter)
25 11
    {
26 11
        $this->manipulatorFactory = $manipulatorFactory;
27 11
        $this->migrations = $migrations;
28 11
        $this->io = $io;
29
        $this->code = $codeWriter;
30 11
    }
31
32 11
    public function run()
33 11
    {
34 11
        $this->db = $this->manipulatorFactory->createManipulator();
35 3
        $files = scandir($this->migrations->getPath("migrations"));
36
        if (count($files) > 2) {
37 8
            throw new NonReversibleCommandException("Cannot run imports. Your migrations directory is not empty");
38
        }
39 8
        $description = $this->db->getDescription();
40 8
41 8
        $this->code->add('begin()');
42
        if (isset($description['schemata'])) {
43 8
            $this->importSchemata($description['schemata']);
44 8
        }
45
        if (isset($description['tables'])) {
46 8
            $this->importTables($description['tables']);
47 8
        }
48
        if (isset($description['views'])) {
49
            $this->importViews($description['views']);
50 8
        }
51 8
52
        $this->importForeignKeys();
53 8
        $this->code->add('->end();');
54 8
55 8
        $this->newVersion = date('YmdHis', time());
56 8
        $path = $this->migrations->getPath("migrations/{$this->newVersion}_import.php");
57 8
        Filesystem::file($path)->putContents($this->code);
58 1
        $this->io->output("Created `$path`\n");
59
        if (!$this->db->getAssertor()->doesTableExist('yentu_history')) {
60 8
            $this->db->createHistory();
61 8
        }
62
        $this->db->setVersion($this->newVersion);
63 8
        $this->db->disconnect();
64
65
        return $description;
66 7
    }
67
68 7
    public function getNewVersion()
69
    {
70
        return $this->newVersion;
71 7
    }
72
73 7
    private function generateSchemaCode($description, $ref = false, $prefix = '')
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
74 7
    {
75 6
        $refprefix = $ref === true ? 'ref' : '->';
76
        if ($description["{$prefix}schema"] == false) {
77 1
            return "{$refprefix}table('{$description["{$prefix}table"]}')";
78
        } else {
79
            return "{$refprefix}schema('{$description["{$prefix}schema"]}')->table('{$description["{$prefix}table"]}')";
80
        }
81 8
    }
82
83 8
    protected function importForeignKeys()
84 7
    {
85 7
        foreach ($this->foreignKeys as $name => $foreignKey) {
86 7
            $this->code->add($this->generateSchemaCode($foreignKey));
87 7
            $this->code->addIndent();
88 7
            $this->code->add("->foreignKey('" . implode("','", $foreignKey['columns']) . "')");
89 7
            $reference = $this->generateSchemaCode($foreignKey, true, 'foreign_');
90
            $this->code->add("->references({$reference})");
91 7
            $this->code->add("->columns('" . implode("','", $foreignKey['foreign_columns']) . "')");
92 7
93
            if ($foreignKey['on_delete'] != '') {
94
                $this->code->add("->onDelete('{$foreignKey['on_delete']}')");
95 7
            }
96 7
97
            if ($foreignKey['on_update'] != '') {
98
                $this->code->add("->onUpdate('{$foreignKey['on_update']}')");
99 7
            }
100 7
101 7
            $this->code->add("->name('$name')");
102
            $this->code->decreaseIndent();
103 8
            $this->code->ln();
104
        }
105 7
    }
106
107 7
    protected function importColumns($columns)
108 7
    {
109 7
        foreach ($columns as $column) {
110 7
            $this->code->addNoLn("->column('{$column['name']}')");
111
            $this->code->addNoIndent("->type('{$column['type']}')");
112 7
            $this->code->addNoIndent("->nulls(" . ($column['nulls'] === true ? 'true' : 'false') . ")");
113 5
114
            if ($column['length'] != '') {
115 7
                $this->code->addNoIndent("->length({$column['length']})");
116 3
            }
117
            if ($column['default'] != '') {
118
                $this->code->addNoIndent("->defaultValue(\"{$column['default']}\")");
119 7
            }
120
121 7
            $this->code->ln();
122
        }
123 8
    }
124
125 8
    protected function importSchemata($schemata)
126
    {
127 8
        $this->code->add('// Schemata');
128 1
129
        if (count($schemata) > 0) {
130
            $this->hasSchema = true;
131 8
        }
132 1
133 1
        foreach ($schemata as $schema) {
134 1
            $this->code->add("->schema('{$schema['name']}')");
135 1
            $this->code->addIndent();
136 1
            $this->importTables($schema['tables']);
137
            $this->importViews($schema['views']);
138
            $this->code->decreaseIndent();
139 8
        }
140 8
141
        $this->hasSchema = false;
142 8
    }
143
144 8
    protected function importViews($views)
145 4
    {
146 4
        foreach ($views as $view) {
147 4
            $definition = sprintf('->definition("%s")', str_replace('"', '\"', $view['definition']));
148
            $this->code->add("->view('{$view['name']}')$definition");
149 8
            $this->code->ln();
150
        }
151 8
    }
152
153 8
    protected function importTables($tables)
154 7
    {
155 7
        foreach ($tables as $table) {
156
            if ($table['name'] == 'yentu_history')
157 7
                continue;
158 7
159
            $this->code->add("->table('{$table['name']}')");
160 7
            $this->code->addIndent();
161 7
162
            $this->importColumns($table['columns']);
163 7
            $this->importConstraints('primaryKey', $table['primary_key']);
164 6
165
            if ($table['auto_increment']) {
166 7
                $this->code->add("->autoIncrement()");
167 7
            }
168
            $this->importConstraints('unique', $table['unique_keys']);
169 7
            $this->importConstraints('index', $table['indices']);
170 7
171
            $this->code->decreaseIndent();
172 7
            $this->code->ln();
173 7
174
            if (count($table['foreign_keys']) > 0) {
175
                $this->foreignKeys = array_merge($this->foreignKeys, $table['foreign_keys']);
176 8
            }
177
        }
178 7
    }
179
180 7
    protected function importConstraints($type, $constraints)
181 7
    {
182 7
        foreach ($constraints as $name => $constraint) {
183
            $constraint = implode("','", $constraint['columns']);
184 7
            $this->code->add("->$type('$constraint')->name('$name')");
185
        }
186
    }
187
}
188
189