Completed
Pull Request — master (#20)
by Pavel
10:22
created

MigrateCommand::execute()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 16
rs 9.4285
c 1
b 0
f 0
cc 3
eloc 9
nc 2
nop 2
1
<?php
2
3
namespace App\Console\Commands;
4
5
use Symfony\Component\Console\Command\Command;
6
use Symfony\Component\Console\Input\InputInterface;
7
use Symfony\Component\Console\Output\OutputInterface;
8
use Illuminate\Database\Capsule\Manager as Capsule;
9
use Symfony\Component\Finder\Finder;
10
11
/**
12
 * MigrateCommand
13
 */
14
class MigrateCommand extends Command
15
{
16
    /**
17
     * @var string Table name where migrations info is kept
18
     */
19
    const MIGRATIONS_TABLE = 'migrations';
20
21
    /**
22
     * Configuration of command
23
     */
24
    protected function configure()
25
    {
26
        $this
27
            ->setName('migrate')
28
            ->setDescription('Command for run migration')
29
        ;
30
    }
31
32
    /**
33
     * Execute method of command
34
     *
35
     * @param InputInterface $input
36
     * @param OutputInterface $output
37
     *
38
     * @return void
39
     */
40
    protected function execute(InputInterface $input, OutputInterface $output)
41
    {
42
        if (!is_dir(MIGRATIONS_PATH) || !is_readable(MIGRATIONS_PATH)) {
43
            throw new \RunTimeException(sprintf('Migrations path `%s` is not good', MIGRATIONS_PATH));
44
        }
45
46
        $output->writeln(['<info>Run migrations</info>']);
47
        $this->safeCreateTable(self::MIGRATIONS_TABLE, $output);
48
49
        $finder = new Finder();
50
        $finder->files()->name('*.php')->in(MIGRATIONS_PATH);
51
52
        $this->runActionFiles($finder, $output);
53
54
        return;
55
    }
56
57
    /**
58
     * Run list of migrations in files
59
     *
60
     * @param Finder          $files list of files to run
61
     * @param OutputInterface $output
62
     *
63
     * @return void
64
     */
65
    private function runActionFiles(Finder $files, OutputInterface $output)
66
    {
67
        foreach ($files as $file) {
68
            $baseName = $file->getBasename('.php');
69
            $class    = $this->getMigrationClass($baseName);
70
71
            if ($this->isRowExist($baseName, self::MIGRATIONS_TABLE)) {
72
                $output->writeln([sprintf('`%s` - already exists.', $baseName)]);
73
                continue;
74
            }
75
76
            require_once($file);
77
78
            $obj = new $class();
79
            $obj->up();
80
81
            $this->insertRow($baseName, self::MIGRATIONS_TABLE);
82
            $output->writeln([sprintf('`%s` - done.', $baseName)]);
83
        }
84
85
        $output->writeln(['<info>Completed.</info>']);
86
87
        return;
88
    }
89
90
    /**
91
     * Return class name by file basename
92
     * @param string $baseName
93
     *
94
     * @return string
95
     */
96
    private function getMigrationClass($baseName)
97
    {
98
        $filenameParts = explode('_', $baseName);
99
        $class         = '';
100
101
        array_shift($filenameParts);
102
103
        foreach ($filenameParts as $key => $filenamePart) {
104
            $class .= ucfirst($filenamePart);
105
        }
106
107
        return $class;
108
    }
109
110
    /**
111
     * @param string          $tableName
112
     * @param OutputInterface $output
113
     */
114
    private function safeCreateTable($tableName, OutputInterface $output)
115
    {
116
        $output->writeln([sprintf('Ensure table `%s` presence', $tableName)]);
117
118
        try {
119
            if (!Capsule::schema()->hasTable($tableName)) {
120
                Capsule::schema()->create($tableName, function($table)
121
                {
122
                    $table->string('version');
123
                    $table->timestamp('apply_time')->useCurrent();
124
125
                    $table->primary('version');
126
                });
127
            }
128
        } catch (\Exception $e) {
129
            $output->writeln([
130
                sprintf('Can\'t ensure table `%s` presence. Please verify DB connection params and presence of database named', $tableName),
131
                sprintf('Error: `%s`', $e->getMessage()),
132
            ]);
133
        }
134
    }
135
136
    /**
137
     * @param $name
138
     * @param $table
139
     * @return bool
140
     */
141
    private function isRowExist($name, $table)
142
    {
143
        $item = Capsule::table($table)->where('version', $name)->first();
144
        return !is_null($item);
145
    }
146
147
    /**
148
     * @param $name
149
     * @param $table
150
     */
151
    private function insertRow($name, $table)
152
    {
153
        Capsule::table($table)->insert([
154
            'version' => $name,
155
        ]);
156
    }
157
}
158